-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Port Rust to PNaCl/JS (rebase #1) #26505
Port Rust to PNaCl/JS (rebase #1) #26505
Conversation
r? @brson (rust_highfive has picked a reviewer for you, use r? to override) |
☔ The latest upstream changes (presumably #25784) made this pull request unmergeable. Please resolve the merge conflicts. |
Possibly a dumb question, but where should I look for the equivalent of kernel / libc headers in PNaCl? I noticed I collided with you on the signal-handling bindings and I was going to make sure they're correct (there were some wrong ones before on other ports), but I also just want to get a sense of what signal-handling even means on PNaCl. In general it'd be useful to have a pointer to the C headers to verify ABI-compatibility. (Also this PR is pretty exciting, I'm looking forward to being able to use this.) |
Thanks @DiamondLovesYou. @alexcrichton or I will review again soon. |
Both @brson and I very much want Rust to run everywhere, so we want to facilitate ports of the Rust to various platforms as much as possible. After looking this over again, however, this is going to need to be scaled back to be more conservative to land. The changes made here remain quite invasive, especially when it comes to LLVM bindings and the backend for emitting this code, and unfortunately with the current impact it's just too much to keep around for a niche platform. Ultimately, it's unclear to me whether all the extra overhead here is worth gaining support to target PNaCl. Specifically, my concerns remain along the lines of:
I'm very worried about investing so much effort in adding support for an unsupported upstream platform in LLVM. We won't have any automated testing for any of this support, and it seems like it's highly susceptible to going out of date quickly. I would still love to support PNaCl, however, so I'm curious if any of the following strategies would suffice:
|
@geofft From the PNaCl toolchain root (ie |
Update: Once https://codereview.chromium.org/1207543003 lands, the changes in |
PNaCl has a lot of similarities with emscripten, so this PR could also open the door to adding support for emscripten! |
@tomaka The plan is to use PNaCl as an intermediary, with another tool (possibly in the NaCl SDK) to run the Emscripten passes (ie the passes not run for PNaCl bitcodes) and finally codegen for JS. |
@DiamondLovesYou I'm pretty interested in playing around with this. Could you advise how to compile it? Is a particular llvm + patches required? I've attempted to use pepper_canary and pnacl-llvm/master but rustc just fails to build itself with a FPE. |
@AerialX You can't currently. 😦 Once that's done however, it might still not work. Because of the aforementioned bug, I haven't been able to test anything PNaCl related. If you'd still like to target PNaCl, the master branch on my fork might still work with one of the previous |
@alexcrichton @brson Could I get a re-review? There are still a few changes left in |
@alexcrichton Re webasm, it does appear that webasm is the inevitable endgame for both emscripten and pnacl, and seems very likely that any support for the latter will be obsoleted by the former within a few years. @DiamondLovesYou Yes, one of us will take another pass soon. |
@brson Alright, thanks! |
@DiamondLovesYou This is looking a lot better, but I've still got a number of concerns:
Also, what's the upstream status of this? Is this in upstream LLVM or is a fork still required? I would also be pretty concerned if a fork were still required |
a850873
to
6d340e0
Compare
I've added comments. Is that satisfactory?
I'm sorry, but the one attribute is necessary so traditional CLI applications can be made to work as a PPAPI plugin and in a way that's compatible with
Fine; removed.
Not really, it's specified as a build flag for
Ah, those were leftovers I forgot to remove. Fixed!
Strictly speaking, currently, no, a fork is not required. I've made all the changes necessary to use PNaCl's LLVM though, so one can still use it to say reduce the build time. I currently use the prebuilt LLVM from the SDK in my builds because I'm trying to get the Rust compiler into the NaCl SDK. That said, in the past its been a different story. The difference in LLVM's version between Rust's LLVM && PNaCl's LLVM used to make it quite difficult to use the toolchain with Rust: while LLVM's bitcode format is supposedly stable, that doesn't say anything about the meaning of the bitcode. For example, debugging info metadata. Anyway, Rust's LLVM is itself a fork, so what's the big fuss? |
Is this usable now? I tried it with |
@AerialX Literally not 15mins ago, I managed to kill the last bug in It'll be awhile before the forthcoming patch lands in I appreciate you enthusiasm though! 😃 |
Haha, sorry, the way you commented made it sound like it was working with upstream pnacl-llvm :) I'll see about building my own from source if I get some free time! |
7f98ee4
to
47f70b2
Compare
This is an attribute in the stable set of rust which will need to be supported until the end of time, these sorts of additions are not taken lightly and we have a process for including new features into the stable set of Rust. Features (like attributes) start behind a feature gate and then later get un-feature-gated.
Why not just use the normal |
Guh habit of hitting "comment" too soon...
Rust does not require a fork, we have a few small performance-related patches we haven't bothered sending upstream yet, but it's quite important to us that we work with upstream LLVM right now. You can build Rust against the system LLVM for example, and the full test suite should pass (assuming a relatively recent system LLVM). I'm very wary of adding so much code needed to support a new platform that's (a) on the way out to being deprecated and (b) doesn't work unless you recompile all of Rust against a custom LLVM toolchain. |
da0a768
to
4c777b0
Compare
☔ The latest upstream changes (presumably #27210) made this pull request unmergeable. Please resolve the merge conflicts. |
@alexcrichton Sorry for the delay.
After realizing I am an idiot (yet again!), I just changed it to just use
Because Newlib isn't unique to NaCl (even though NaCl's Newlib isn't completely vanilla). In the future, if another port requires use of Newlib, some of the work will already be done. At least that is my intention.
Well, by that measure, neither does this PR. You can technically still use I suppose I should say 'should' instead of 'must'. Anyway, this PR still works as expected with upstream LLVM if one doesn't care about targeting PNaCl/JS, the current Travis CI failure notwithstanding.
When the time comes, and wasm descends from the Heavens to become, as foretold in the Great Prophecy, the Lord and Savior of all web developers who'd rather not use JS, I will likely be the one to remove/deprecate the old NaCl code and replace it with wasm code. However, Wasm is at least a year and a half out (even then it'll likely be polyfill only). And JS won't be deprecated until way after that. |
Would it help if I split this patch up into less scary PRs that more amenable to code reviewing? It's been mentioned several times that this changeset is huge (even though the net diff now is much less than the total lines +/- reported), so I think if I submitted my work incrementally (instead of submitting it all at once) it would be easier for all of us to agree and would give me more helpful suggestions for what is wanted before code is accepted. |
1d40e19
to
21ea047
Compare
Sorry for being a little slow to respond! When @brson and I mention that this is a huge PR, it's not so much the size so much as the scope of the changes made here. We have 0 automation for any of the changes beyond that they parse, so there's an very high chance of bitrot for all of this coming in. Most "port to a new platform" is just some definitions in liblibc, tweaking a custom target spec, and possibly adding a few
It would be best if this continued the trend of being as minimal as possible when porting to a new platform. For example not making the changes necessary to run the compiler itself on pncal would be a good start (this isn't necessary, right?). Additionally, scaling back as much as possible in the compiler itself to ideally require 0 changes would be best. For example the "if nacl" logic for intrinsics and SIMD operations seems particularly hairy and would be good to simplify. The size of this PR is fine to me, but breaking up into separate commits is generally quite useful. For example there's a few separable parts you may want to extract:
(etc) Some specific changes I would recommend are:
|
Android && iOS's instructions were retreived from the old wiki.
7e3c9df
to
e4a1921
Compare
FYI thanks for doing this -- I'm very much looking forward to having this work. |
I know these reviews have been brutal, but I've given this another once over and taken some unorganized notes, with commentary. My main interest is understanding the intersection of PNaCl, emscripten, and webasm requirements and making sure we don't do too much that is PNaCl specific. What the PNaCl patch does:
|
I'm feeling like there's a reasonable path forward here, and want to sit down with @alexcrichton and discuss. |
I've been looking into the existing emscripten ports, posted a patch to update the build tool. I discovered that the std used for that project is really hacked up. |
@brson wow those changes w.r.t w/ overflow are using really old macros I wrote for this port a long time ago, and they're actually no longer needed because the PNaCl IR simplification passes now handle them (Emscripten uses most of the PNaCl IR passes itself). Anyway, I'm working on my reply to your big comment, I should have that finished shortly-ish. |
Oh awesome! That'll be a nice chunk that we don't have to deal with any more. |
@alexcrichton Be warned though, I have no idea how up-to-date Emscripten's PNaCl passes are. They obviously don't have the changes I've make to Emscripten should really, really be targeted via PNaCl though. This is because even By using PNaCl, the toolchain can handle the IR simplification and then because it's output will be just bitcode, one can, after adding the Please don't let my apparent focus on PNaCl make one think I don't care about Emscripten. |
God I wish quoting people was easier.
This part was actually split into it's own PR. I have to say though, being able to use a shared object of LLVM is awesome, for the obvious reason that LLVM can be rebuilt without requiring a rebuild of Rust as well.
Used to be for convenience. The command line option was actually left on accident and is completely ignored ( @alexcrichton ) . I just forgot to remove it after I removed all the code/logic that used it. I'll get this fixed.
NaCl is technically distinct from PNaCl though. One can target NaCl directly through PNaCl, with the appropriate flags (not in a way that would be valid PNaCl Pexe bitcode, however). I'd like to keep the tests w/
Fair enough, I'll remove them.
This doesn't modify stdlib's intrinsic defs to use libm at all. What stdlib does do is to redirect some of the smaller overloads to their larger brethren or to an identical except for type version that libm actually provides. Ie Std only casts. Trans is the only place that actually does the unsupported intrinsics redirection to libm.
Not really. While LLVM does have facilities for lowering such intrinsics, such facilities are only available to target machines (via SelectionDAG). Thus PNaCl can't use them. Yes I have considered creating a target machine for PNaCl. Possible, but a lot of work.
Rust is not the only compiler out there. I appreciate that you want to keep churn at bay (even if I frankly disagree with Rust's aversion to such, given that this is an unsupported port anyway (and an evolving one at that)). I mean no disrespect (really!): I have no indention of dumping this on the Rust team and then just disappearing; rather, I'd like to be considered an 'owner' of these platforms (to this end, my IRC visitation habits could probably use some work; I always forget about IRC), given how long I've been working on this port.
An unfortunate kludge; fixable in LLVM but harder and requires more work to do so. Also this PR is old (that one SIMD rfc was accepted) and these polyfills conflict with the new APIs.
Yes and no. Yes NaCl uses Newlib, but no that wouldn't completely work because NaCl's Newlib isn't vanilla. That said, I thought I set the target details to use 'newlib' for target_env anyway...
Except PNaCl, JS, and WAsm don't use an assembler and wouldn't use LLVM's inline assembler expressions anyway. PNaCl has no use case (outside of direct-to-NaCl mentioned above), JS uses In PNaCl's case, the only manifestation of this error will be a "linker" error (as in
So are the other
No assembling is ever done (as far as Rust is concerned at least;
Huh? Where?
Trans only redirects LLVM intrinsics to their libm equivalents. Intrinsics that can be emulated with a cast live in std.
Hm. I don't remember. I'm checking locally; assuming a couple of PNaCl's run-tests pass, I'll remove it.
Because the vectorizer will produce odd sized vector types, ie not 128bit wide. There is no IR level simplification/canonicalization pass to fix this, and it isn't exactly a trivial pass to write (though if (only) PNaCl had a real target machine, SelectionDAG could help out). In fact, it's impossible to do on non-simplified (in the PNaCl IR sense) IR without adding a new instruction (or accepting a perf loss). I have a pass in the works to solve this issue though. Once finished it'll also be of great benefit to C/C++ PNaCl.
Until WAsm gets dynamic linking (which is post-MVP), all three of the virtual ISA targets delay codegen until after linking. Both PNaCl && Emscripten use LLVM bitcode as their object format; and I bet WAsm will too, until dynamic linking is added at least.
This isn't a LLVM/PNaCl issue: PNaCl isn't limited to a max alignment of eight. This is an issue of Rust, which embeds zero sized arrays of a type with a specific alignment into trans-ed LLVM structures (for enums I believe) to force alignment. I was the one who originally added the hack to use vector types to force alignment, but unfortunetly the hack can't work when the DataLayout doesn't specify a vector alignment of 128bits (which most other platforms do, apparently). I haven't tried this yet, but I'll try overriding PNaCl's default DataLayout with a vector alignment of 128bits (ie force the datalayout to have a vector alignment of 128bits). I'll add a comment to update you when I get around to this (I'm in college currently, but I'll get to it when I can).
PNaCl's LTO is based on the same LLVM module linking code as Rust's. PNaCl's is much better though (because all deps are bitcode linked, not just Rust deps) and it make's Rust's LTO redundant. PNaCl/Emscripten is always LTO (well, obviously not
Not sure what 'this branch' refers to, but Rust's LTO is redundant, so requesting it should be a no-op. FWIW, I'm open to making it a warning on
I don't think the change is a terrible idea in general though (I'm honestly not sure what LLVM does for these large volatile loads).
Not needed unless
If one considers returning ESYS as handling it, then NaCl does. Unfortunately in PNaCl's case, Rust checks the return value.
See the comment in the unwinding personality function. The function is never called.
On my TODO.
Not really all that ugly, considering that I'd have to plaster Is it really that bad for shared implementation helpers to be unused? At any rate, it is possible to implement crude, non-zero cost, backtracing by having
It's LTO. Literally. PNaCl uses a bitcode linker (ie ld.gold). So passing
Must be a leftover I forgot to remove. I'll get it fixed. FYI, I'm splitting this PR up, so it's easier to review. Damn that was a novel. |
Note that this was for an overnight PoC, and a lot of it isn't necessary. Getting std in line isn't much of a problem, and doing it properly isn't too much work. The main things emscripten doesn't support are threads+TLS and backtracing.
And there's the rub, isn't it? It would just make too much sense for these virtual ISAs to expose themselves as a target machine so that downstream compilers wouldn't need any special knowledge about them. If this is so difficult to do (as evidenced by PNaCl using such a hacked-up LLVM), it seems indicative of a problem with LLVM's architecture. One can only hope that wasm ends up being more sane... In any case, I do believe that getting this working is the way forward for Emscripten to work for the forseeable future. LLVM is too much of a moving target for it to ever work without rustc explicitly being compiled against the same version. The rest (std changes, codegen+trans changes) isn't strictly necessary, but would be nice. ... and I still haven't managed to get rustc/rustllvm to compile against a PNaCl LLVM, all these C++ API changes and |
On Thu, Sep 3, 2015 at 10:11 AM, Aaron Lindsay [email protected]
|
From your comment on #28355 it sounds like many of the pieces of this have landed and that's the final piece necessary for pncal support, so closing in favor of that. I can certainly reopen of I'm mistaken though! |
Fine with me. On Sun, Sep 13, 2015 at 12:43 PM, Alex Crichton [email protected]
|
This is a rebase of #26148 for the LLVM 3.7 changes. See #26148 for the previous set of comments. I've created a new PR so the original comments won't disappear.