Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upUpgrade to nightly #39
Conversation
joshuawarner32
added some commits
Sep 10, 2016
joshuawarner32
reviewed
Sep 10, 2016
| @@ -534,6 +532,16 @@ impl<'v, 'tcx: 'v> BinaryenFnCtxt<'v, 'tcx> { | |||
| TerminatorKind::Return => { | |||
| /* handled during bb creation */ | |||
| } | |||
| TerminatorKind::Assert { ref target, .. } => { | |||
| // TODO: An assert is not a GOTO!!! | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
joshuawarner32
reviewed
Sep 10, 2016
| } | ||
| } | ||
| } | ||
| // if self.sig.output == ty::FnOutput::FnDiverging { |
This comment has been minimized.
This comment has been minimized.
joshuawarner32
Sep 10, 2016
Author
It wasn't clear what to do in this case. FnOutput was removed in a recent refactor (see: rust-lang/rust@ed02344).
This comment has been minimized.
This comment has been minimized.
eddyb
Sep 10, 2016
self.sig.output.is_never(). But also, this whole block is a very lengthy way to do Some(self.did) == tcx.lang_items.panic_fn() (which doesn't require the check for the return type).
joshuawarner32
reviewed
Sep 10, 2016
| @@ -719,6 +727,48 @@ impl<'v, 'tcx: 'v> BinaryenFnCtxt<'v, 'tcx> { | |||
| } | |||
| } | |||
|
|
|||
| Rvalue::CheckedBinaryOp(ref op, ref left, ref right) => { | |||
| // TODO: This shouldn't just be a copy BinaryOp above! | |||
| // We should do some actual _checking_! | |||
This comment has been minimized.
This comment has been minimized.
joshuawarner32
Sep 10, 2016
Author
This is obviously not correct. I may take a second look this weekend.
This comment has been minimized.
This comment has been minimized.
eddyb
Sep 10, 2016
This needs either support for ops that also return the overflow bit, or emulation thereof.
This comment has been minimized.
This comment has been minimized.
joshuawarner32
Sep 10, 2016
Author
On second thought, this would be much easier to do with a call to an emulation function, and letting binaryen (or downstream jit compilers) inline that as appropriate. Is there precedent for doing that sort of thing?
This comment has been minimized.
This comment has been minimized.
eddyb
Sep 10, 2016
Having that emulation written in Rust instead of generating it? Depending on what the internal API is of mir2wasm, it could be just as easy to emit the right code here (and you wouldn't have compiler-implementation dependencies).
This comment has been minimized.
This comment has been minimized.
joshuawarner32
Sep 10, 2016
Author
I was actually not thinking of writing it in rust, though that's also a good idea. The problem I'm trying to avoid is that checked operations tend to do a number on the local control flow - and I haven't fully wrapped my head around the binaryen APIs needed to implement that. Just emitting a call makes this really easy. But I could easily be dramatically overestimating the complexity of just doing it the obvious (inline) way.
This comment has been minimized.
This comment has been minimized.
|
FYI, I was just playing around with this (awesome stuff!). I thought this might be helpful. If not, don't hesitate to close this. No worries. |
eddyb
reviewed
Sep 10, 2016
| @@ -282,6 +277,9 @@ impl<'v, 'tcx: 'v> BinaryenFnCtxt<'v, 'tcx> { | |||
| StatementKind::Assign(ref lvalue, ref rvalue) => { | |||
| self.trans_assignment(lvalue, rvalue, &mut binaryen_stmts); | |||
| } | |||
| StatementKind::StorageLive(ref var) => {} | |||
| StatementKind::StorageDead(ref var) => {} | |||
This comment has been minimized.
This comment has been minimized.
eddyb
reviewed
Sep 10, 2016
| Lvalue::Temp(i) => { | ||
| let i: u32 = unsafe { mem::transmute(i) }; |
This comment has been minimized.
This comment has been minimized.
eddyb
Sep 10, 2016
Never, ever use transmute except as a last resort. These newtypes have an API for getting their index integer.
Besides, this computation has been replaced with local_index or something like that, also used by rustc_trans.
This comment has been minimized.
This comment has been minimized.
joshuawarner32
Sep 10, 2016
Author
Fair. I had a hell of a time finding the definition of the Temp struct (in this case). I think I was just taking out my frustration on the code. :)
I just pushed a fix to use i.index() instead. Is that what you mean by local_index - or is there an even better way to simplify this?
eddyb
reviewed
Sep 10, 2016
| @@ -1034,7 +1091,7 @@ impl<'v, 'tcx: 'v> BinaryenFnCtxt<'v, 'tcx> { | |||
|
|
|||
| #[inline] | |||
| fn type_size(&self, ty: Ty<'tcx>) -> usize { | |||
| let substs = self.tcx.mk_substs(Substs::empty()); | |||
| let substs = Substs::empty(*self.tcx); | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
joshuawarner32
Sep 10, 2016
Author
Nope, but Substs::empty takes a struct, not a reference. FWIW, that seems like a common pattern with TyCtxt: lots of functions ownership of it, but the TyCtxt has #[derive(Clone, Copy)] on it. Just glancing at it, I hope the compiler is doing some magic to eliminate those copies, because TyCtxt is a pretty big struct.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
joshuawarner32
Sep 10, 2016
Author
Ah, you're right. Somehow my eyes just glazed over the &'a part of those fields. For posterity: https://github.com/rust-lang/rust/blob/f2b672d5567c3b20542e845baaf8a9c47d9df907/src/librustc/ty/context.rs#L285
eddyb
reviewed
Sep 10, 2016
| } | ||
| } | ||
| } | ||
| let mut is_fn_panic = Some(self.did) == self.tcx.lang_items.panic_fn(); |
This comment has been minimized.
This comment has been minimized.
eddyb
Sep 10, 2016
This shouldn't be mut. In fact, it's only used once, in the condition below. If you switch the "then" and "else" bodies, you can use this comparison as the condition.
Similar story with is_entry_fn which could be Some(nid) == self.node_id below.
joshuawarner32
added some commits
Sep 10, 2016
This comment has been minimized.
This comment has been minimized.
|
Thanks @joshuawarner32 ! @eholk do you want to take a peek at this before I blindly merge? |
This comment has been minimized.
This comment has been minimized.
|
I'd like to take a look. I should be able to get to it this afternoon. I On Tue, Sep 13, 2016 at 2:59 PM Brian Anderson notifications@github.com
|
This comment has been minimized.
This comment has been minimized.
|
@brson Also be aware that several of the caveats mentioned above still apply; I haven't gotten a chance to look at the handling of Asserts and CheckedBinaryOperations. Also, the only testing I've done is to run Also, I just saw rust-lang/rust#36339 (llvm-based wasm) - does that mean mir2wasm is not the "right" direction to go? |
This comment has been minimized.
This comment has been minimized.
Both approaches (mir2wasm and llvm-based) are worthwhile in my opinion. Each has different things that makes it useful:
|
This comment has been minimized.
This comment has been minimized.
|
I'd like to see
I'm guessing @brson or someone else on the Rust team knows how to fix this pretty readily. Incidentally, I had a similar in progress branch with the same problem. Just from a cursory look, @joshuawarner32's version seems better overall, since it seems to actually handle a few cases that I just aggressively deleted. It'd also be good to update the readme with the specific Rust nightly that this builds with so that we have a known good revision the next time nightly breaks us. |
This comment has been minimized.
This comment has been minimized.
|
@joshuawarner32 Thanks for the caveats. Since this is such an early prototype still I'm happy to endure some breakage, as long as it looks good to @eholk and/or @lqd. And as @kripken mentioned, there are reasons to pursue both approaches, so even once the LLVM-based approach is merged I intend to keep plugging away at this one. Maybe @eddyb can see what's being generated incorrectly to cause that. Otherwise I can poke at it later. |
This comment has been minimized.
This comment has been minimized.
|
I guess a totally legitimate way to make the tests pass in this case is the xfail the failing ones. @brson's point about enduring breakage on an early prototype is a good one; it's probably better to track nightly a little closer than we're doing than have production-quality tests. |
eddyb
reviewed
Sep 14, 2016
| match fulfill_obligation(tcx, trait_ref) { | ||
| traits::VtableImpl(vtable_impl) => { | ||
| let impl_did = vtable_impl.impl_def_id; | ||
| let mname = tcx.item_name(def_id); | ||
| // Create a concatenated set of substitutions which includes those from the impl | ||
| // and those from the method: | ||
| let impl_substs = vtable_impl.substs.with_method_from(substs); | ||
| let substs = tcx.mk_substs(impl_substs); | ||
| let substs = substs.rebase_onto(*tcx, def_id, vtable_impl.substs); |
This comment has been minimized.
This comment has been minimized.
joshuawarner32
added some commits
Sep 14, 2016
This comment has been minimized.
This comment has been minimized.
|
@eholk: Not sure if this helps, but based on some println debugging, it looks like the For example, here's some of the relevant values as they appear at trans.rs:1083, just before the ICE (appogies for the horrible formatting; you can see the line number at the very end of that third line):
|
This comment has been minimized.
This comment has been minimized.
eddyb
commented
Sep 14, 2016
|
@joshuawarner32 Did my suggestion not fix it? |
This comment has been minimized.
This comment has been minimized.
|
Sorry I haven't had the time to check this out (and am unfortunately unlikely to be able to do so in the immediate future) however there were a couple of things I thought I needed to mention
|
This comment has been minimized.
This comment has been minimized.
|
@eddyb - I didn't notice a difference in the outcome of the tests after I implemented your def_id to trait_id suggestion. But it does make sense - at least to someone with only a glancing familiarity in this code. @lqd - Do you have a concrete suggestion on how to pull that in? It's not immediately obvious to me how to adapt that to the current interface. The only parts that look remotely equatable is the Tiny bit of incremental progress on the internal compiler error. The following snippet seems to be the minimal code needed to trigger the error. Removing the body on the method defined in the pub trait Test {
fn test(&self) { } // removing the body here gets us passed the ICE
}
impl Test for isize {
fn test(&self) { }
}Does that ring a bell for anyone? |
This comment has been minimized.
This comment has been minimized.
eddyb
commented
Sep 15, 2016
|
@joshuawarner32 Sounds like it uses the default body even when the method is implemented - but it's not using the trait substs, but the impl ones, with the trait default method. |
This comment has been minimized.
This comment has been minimized.
|
@joshuawarner32 yes:
(There were also a couple of different error handling suggestions from eddy which miri didn't implement at the time) It's very possible that this doesn't fix the issue indeed, but at least you won't have to update the current traits module to the newer rustc API. It's not a problem if it doesn't fix it either, if @eholk is happy with the PR, I'd say let's merge it to get the benefits of the newer nightly, and then deal with this — as we'll have to fix other monomorphizations cases anyway! |
This comment has been minimized.
This comment has been minimized.
|
Hmm, does binaryen still print out the result of running a program? It looks like some of our tests aren't showing the expected output. For example,
doesn't give me any output, but the test is expected to print |
This comment has been minimized.
This comment has been minimized.
|
@eholk: Perhaps you're referring to I tracked that down to a problem with how I assumed checked ops would work in mir. How they actually work is the <side-note>Longer term, it's probably best to model (non-escaping) structs on the stack as exploded locals. Otherwise, the optimizer is going to have one hell of a time cleaning that up, since the WebAssembly memory model doesn't allow eliminating that store. But I bet that could easily become a rat's nest.</side-note> |
joshuawarner32
added some commits
Sep 16, 2016
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I just tried xfailing the tests that were failing, and unfortunately I ran into another issue. It looks like there's a deps test that runs afterwards and that is segfaulting now, at least for me. It seems to be trying to call a destructor on an Here's the stack:
I'm tempted just to go ahead and open a bug to track this new issue and merge this PR, because I'd like to get it merged. |
This comment has been minimized.
This comment has been minimized.
|
@eholk - then let me take a stab this evening at isolating the portions of the tests that are actually causing the ICE, and mark just those parts as xfail. I'd rather have mostly-working tests than mostly-broken tests. |
This comment has been minimized.
This comment has been minimized.
|
@joshuawarner32 - sounds good! I like mostly working tests too :) As long as you're okay to keep working on them, I'm happy to wait. I just don't want you to feel like I'm putting up arbitrary roadblocks for you or anything like that. |
This comment has been minimized.
This comment has been minimized.
|
an std::vector & libstdc++ ? is this related to binaryen ? |
joshuawarner32
added some commits
Sep 20, 2016
This comment has been minimized.
This comment has been minimized.
|
@eholk - I modified / xfailed the appropriate tests, and now everything seems to be passing. Also, I'm not able to reproduce the |
This comment has been minimized.
This comment has been minimized.
|
Sorry @joshuawarner32, I didn't notice your update to this a few days ago. I tried it on my mac and also didn't see the crash. In the interest of moving things forward, I'm going to accept this and open an issue about the crash I'm seeing on Linux. @lqd - I have some suspicions that it might be related to binaryen, but I don't have any real evidence to base this on yet. |
eholk
merged commit 6aa925e
into
brson:master
Sep 23, 2016
This comment has been minimized.
This comment has been minimized.
|
Thanks @joshuawarner32! and thanks @eholk of course as well! |
joshuawarner32 commentedSep 10, 2016
NOTE: Do not merge yet! Shenanigans abound!
... but on the surface it seems to work.