-
Notifications
You must be signed in to change notification settings - Fork 66
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
Enabling features by default in LLVM #158
Comments
Thanks for reviving this issue. I seem to remember it was something I meant to do a while back. Aside from the issue of what to do when in LLVM, did we agree that binaryen and emscripten should be in sync with LLVM (i.e. was there any reason not to have them all be in sync?) |
I don't remember having discussed what to do with other tools, but IMO having them match LLVM seems reasonable. |
Same with WABT. You don't really want these tools to error on every LLVM generated binary because |
For Binaryen this generally wouldn't be an issue because it reads the target features section by default. I assume WABT is more frequently used with binaries that have had their target features section stripped, though. |
Yeah I think it makes sense for all tools to stay in sync. They should all probably strive for an |
Is this criteria decided? As someone who works in non-web browser
What's the mechanism to decide this as doing things in this way hurts places like IOT, or others where HOST programs cannot be updated due to various reasons at the same pace. This essentially locks application writers that target wasm to run on those host programs to a particular rust version (as WASM and WASI evolve). In the case of wasi, this may be alleviated by having stdlibs independent of rustc releases (not possible today tho). E.g. if we could use the latest rust with a stdlib from 3 versions ago, then the addition of new wasi capabilities for This also goes towards a more philosophical discussion of what does it mean to have targets in stable rust and what guarantees those build targets are going to be held against but this is probably not the right forum to discuss it I think. |
Presumably rust, like any other toolchain, will need some way to disable certainly features at compile time if they hope to target older/legacy runtimes? If not, then its output would only be use-able on platforms that support the same set of defaults (i.e. no legacy targets). Another option for toolchains (other than allowing feature selection on the command line) is to use a tool like binaryen to remove the use of certain features, post link. This would allow the compiler itself to be less configurable, and delay feature selection until a late phase. (Obviously this only works for features that can be polyfilled or re-written away) |
I like the disable feature for defaults that break backwards compatibility. E.g. Threads won't break anything as now for example rust panics whenever you try to instantiate a thread, so having it panic because it can't find some functionality after threads are moved into the default feature set doesn't really qualify as breaking. But in the case they are breaking, we could add flags to disable those once they move into the default set of features. The case i'm describing isn't the majority so adding some flags to remove breaking stuff makes sense |
As well is individual features tools can/should probably provide an |
The proposed wording at the top of this issue talks about browsers, which doesn't address major non-Web engines. And even among browsers, there are different versions. And the idea of documenting a 6-month waiting period feels too rigid. Some features have taken engines longer to implement. Others were implemented before reaching stage 4. Even if we wrote words to pin these things down more, for the foreseeable future I expect we'd still end up adding an informal decision-making on top for each feature anyway. So I've now added a comment to this proposed LLVM patch which just says: +// This includes features that have achieved phase 4 of the standards process,
+// and that are expected to work for most users in the current time, with
+// consideration given to available support in relevant engines and tools, and
+// the importance of the features. |
I agree some amount of informal reasoning is necessary. But I do hope we can do that in a cross-ecosystem way, that is, avoid differences between toolchains. In some sense maybe it's ok if say Emscripten is web-focused and makes choices based on browsers, and WASI-libc is server-focused and chooses based on server VMs, and maybe those choices end up different sometimes. But if it would be possible to make a single set of decisions across the entire ecosystem I think that simplicity would have benefits. |
@kripken Do you have a concern about the wording of the comment above, or about the selection of proposed features in the patch: bulk-memory, mutable-globals, nontrapping-fptoint, and sign-ext? |
The wording seems ok to me. About the selection, I'd be happiest if we knew we were also going to enable those precise features in Emscripten shortly. I'm not sure of current plans there (@sbc100 @dschuff ?). But I guess my larger suggestion is, it might be nice if we decided at the level of the entire ecosystem on the set of features rather than doing so in separate toolchains. I don't feel terribly strongly, though - I think that would have benefits, but minor, so if it slows progress maybe it's not worth it. |
In terms of switching emscripten defaults, we need to decide when we're ready to break users on old devices with the default build, and finish getting the tools and/or documentation in place to help developers target them. For the first question, the long pole on the web is nontrapping and bulk memory, shipped in Safari/iOS 15, which Apple says is on about 90% of phones and 80% of tablets released in the last 4 years. Then we need to decide whether we want to expand the use of the -s MIN_SAFARI_VERSION etc flags at compile time, or lower features away at link time with Binaryen as mentioned above, or just have a doc that says "if you want to target Safari 15, use the following feature flags". Regarding the ecosystem I think it would be nice to all move together too, and if we can get get this first step coordinated we'd at least have done the easy first step. It wouldn't necessarily surprise me if there were some SDK in the future that went their own way; that was basically the sentiment expressed above that people might not want to wait on Safari to implement something to enable a feature in some completely unrelated embedding. But if we coordinate LLVM itself, at lease we're applying a nudge in that direction. |
I've now updated D125729 to remove bulk-memory and nontrapping-fptoint. Does anyone have any objections to the patch now? |
sgtm. It does seem safer to not enable features by default that won't work on almost 20% of a major platform like iPhone, since it says only 82% of all iPhones are at 15. (I don't see a reason to focus on just those released in the last 4 years @dschuff ?) Also just 72% of iPads, which is a smaller market, but still that's almost 30%. I guess iOS ties major Safari updates to OS updates? Especially unfortunate as apps can't ship their own browser engines. |
Technically, on ios & mac, safari updates are not always connected to os upgrades. |
@fgmccabe Major versions, or security updates? (I did some searching and can't find a clear answer, but I'm not an Apple user so maybe I don't know the right terms.) |
Definitely both. It's a mostly transparent process on ios: apps are 'just updated' every so often, whenever the developer releases a new version. This appears similar to how chrome is updated in the background too. |
@fgmccabe, that seems to contradict the information that apple supplies on how to update safari: https://support.apple.com/en-us/HT204416: "If a Safari update is available, you can get it by following the steps to update or upgrade macOS, iOS, or iPadOS." |
Well, I have seen those message too. I have also experienced it being upgraded without (esp on ios). But, my experience is stricly anecdotal. |
On macOS, it's definitely possible (at least in recent times) to update just Safari alone (though not always to the latest Safari version if your version of macOS is old enough that support has been dropped). For example, if I'm on macOS major version N - 1 (where N is the latest), sometimes the latest Safari is available as a standalone update. The Safari version history on Wikipedia shows that each release is available for multiple macOS versions: On iOS, as far as I've seen over the last ~5 years at least, Safari is always tied to the overall iOS system version. I have iOS app auto-updates disabled and review each app updates manually before installing them. I do not recall seeing a Safari standalone update on iOS. Once again, the Safari version history on Wikipedia supports this by showing each Safari is connected to an iOS version: So to summarise, AFAIK only macOS allows installing Safari separately from the overall OS version. In recent times, only the previous 1 or 2 macOS versions have been supported by the latest version of Safari.
That wording doesn't really help with this particular question because (at least on macOS where I have seen standalone Safari updates before), they are delivered through the same settings UI flow for upgrading the overall system version. You have to manually choose to install only the Safari update and not the latest macOS (they appear as separate line items that can each be unchecked). |
As an update here, D125729 updating LLVM to enable mutable-globals and signext has now landed. |
While this didn't happen, what about enabling multi-value by default in LLVM 18 or 19 (can look into a PR if this might be a good idea)? Considering the guideline that was added in D125729 about what to enable by default, implementation support as well as the utility value (see for instance this comment):
|
@sbc100 RLBox uses both import-memory and import-table because of the following high level constraints
I can offer more concrete/specific examples if needed. |
Note that the symbol is also similarly undefined in most if not all the other files in the archive, but that doesn't cause a problem. Only the one in crt1-command.o does. As in, if you get rid of the one in crt1-command.o somehow, then it links fine. |
Indeed, this looks like a wasm-ld a bug. I will look into it. |
…d symbols When an undefined symbol is referenced from more than one file we were reporting all undefined symbols as originating from just one of them. This came up while working on WebAssembly/tool-conventions#158 where undefined symbols in one object file were being reported as coming from another.
It looks like there are actually two bugs here. The first one was mis-reporting the source of the undefined symbols references. They are actually coming from |
…d symbols When an undefined symbol is referenced from more than one file we were reporting all undefined symbols as originating from just one of them. This came up while working on WebAssembly/tool-conventions#158 where undefined symbols in one object file were being reported as coming from another.
…e types When reference types are enabled clang will generate call_indirect instructions that explicitly reference the global `__indirect_function_table` symbol. In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158
…e types (#97451) When reference types are enabled clang will generate call_indirect instructions that explicitly reference the global `__indirect_function_table` symbol. In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158
…d symbols (#97444) When an undefined symbol is referenced from more than one file we were reporting all undefined symbols as originating from just one of them. This came up while working on WebAssembly/tool-conventions#158 where undefined symbols in one object file were being reported as coming from another.
…e types (llvm#97451) When reference types are enabled clang will generate call_indirect instructions that explicitly reference the global `__indirect_function_table` symbol. In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158
…d symbols (llvm#97444) When an undefined symbol is referenced from more than one file we were reporting all undefined symbols as originating from just one of them. This came up while working on WebAssembly/tool-conventions#158 where undefined symbols in one object file were being reported as coming from another.
…e types (llvm#97451) When reference types are enabled clang will generate call_indirect instructions that explicitly reference the global `__indirect_function_table` symbol. In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158
…d symbols (llvm#97444) When an undefined symbol is referenced from more than one file we were reporting all undefined symbols as originating from just one of them. This came up while working on WebAssembly/tool-conventions#158 where undefined symbols in one object file were being reported as coming from another.
We were prepared to enable these features [back in February], but they got pulled for what appear to be unrelated reasons. So let's have another try at enabling them! Another motivation here is that it'd be convenient for the [Trail1 proposal] if "trail1" is a superset of "generic". [back in February]: WebAssembly/tool-conventions#158 (comment) [Trail1 proposal]: llvm#112035
The original issue here is resolved in D125729. "generic" will evolve over time, as features are implemented in engines. #233 is a discussion about the specific feature of reference-types being enabled by default in LLVM 19, and the change to People interested in feature sets may be interested in #235, which proposes Trail1, a new table target "CPU" configuration for LLVM. Also relevant here is that I've now submitted llvm/llvm-project#112049 to LLVM to enable nontrapping-fptoint and bulk-memory. They were planned to be enabled here back in February but were reverted for what appear to be unrelated issues, so I'm now proposing to re-add them. And finally here, @sbc100, you mentioned here that there were two bugs. It looks like those were fixed in llvm/llvm-project#97444 and llvm/llvm-project#97451. If that's true, then I propose we can close this issue now. |
Yup, it looks like both issue were fixed. |
Thanks! |
We were prepared to enable these features [back in February], but they got pulled for what appear to be unrelated reasons. So let's have another try at enabling them! Another motivation here is that it'd be convenient for the [Trail1 proposal] if "trail1" is a superset of "generic". [back in February]: WebAssembly/tool-conventions#158 (comment) [Trail1 proposal]: llvm#112035
We were prepared to enable these features [back in February], but they got pulled for what appear to be unrelated reasons. So let's have another try at enabling them! Another motivation here is that it'd be convenient for the [Trail1 proposal] if "trail1" is a superset of "generic". [back in February]: WebAssembly/tool-conventions#158 (comment) [Trail1 proposal]: llvm#112035
We were prepared to enable these features [back in February], but they got pulled for what appear to be unrelated reasons. So let's have another try at enabling them! Another motivation here is that it'd be convenient for the [Trail1 proposal] if "trail1" is a superset of "generic". [back in February]: WebAssembly/tool-conventions#158 (comment) [Trail1 proposal]: llvm#112035
…112049) We were prepared to enable these features [back in February], but they got pulled for what appear to be unrelated reasons. So let's have another try at enabling them! Another motivation here is that it'd be convenient for the [Lime1 proposal] if "lime1" is close to a subset of "generic" (missing only for extended-const). [back in February]: WebAssembly/tool-conventions#158 (comment) [Lime1 proposal]: #112035
…lvm#112049) We were prepared to enable these features [back in February], but they got pulled for what appear to be unrelated reasons. So let's have another try at enabling them! Another motivation here is that it'd be convenient for the [Lime1 proposal] if "lime1" is close to a subset of "generic" (missing only for extended-const). [back in February]: WebAssembly/tool-conventions#158 (comment) [Lime1 proposal]: llvm#112035
…lvm#112049) We were prepared to enable these features [back in February], but they got pulled for what appear to be unrelated reasons. So let's have another try at enabling them! Another motivation here is that it'd be convenient for the [Lime1 proposal] if "lime1" is close to a subset of "generic" (missing only for extended-const). [back in February]: WebAssembly/tool-conventions#158 (comment) [Lime1 proposal]: llvm#112035
I know we discussed this a while ago, but I forget what exactly we came up with @aheejin @dschuff @sbc100 @sunfishcode. IIRC, it wasn't too different from enabling new features once the following two conditions are satisfied:
Am I remembering that correctly? (I couldn't find this discussion in our notes). Should there be a time delay on the second condition as well? I'm thinking about this because multivalue and mutable globals might be eligible to be turned on by default. If so, it would be nice to get that in before LLVM 12 is cut.
The text was updated successfully, but these errors were encountered: