-
Notifications
You must be signed in to change notification settings - Fork 7
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
An error type for trace invalidation. #21
Conversation
tiri/src/lib.rs
Outdated
#[ignore] // FIXME -- This will fail until we investigate why SIR is missing. | ||
fn interp_simple_trace() { | ||
let tracer = start_tracing(Some(TracingKind::SoftwareTracing)); | ||
let res = black_box(work(black_box(3), black_box(13))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely there's no point in doing black_box(3)
-- an integer can't realistically be optimised!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's to prevent constant propagation into the function body. Otherwise the body may be replaced by a value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't the outer black_box
prevent that happening?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not necessarily. The addition could still be removed. Ultimately it's the arguments to the addition operator that we must prevent the compiler from knowing ahead of time.
The outer black box is actually probably not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(It's probably sufficient to only guard only one argument with a black box, too, but having two won't hurt)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's very interesting! black_box
does not work as I expected, which is probably my fault.
OK, so going back to this PR ;) I now think we should drop the outer black_box
call since it doesn't do anything useful in this context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I agree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've also highlighted that the Rust black_box
docs could be improved. I might do a PR against upstream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool!
yktrace/src/errors.rs
Outdated
pub enum InvalidTraceError { | ||
/// There is no SIR for the DefId of a location in the trace. | ||
NoSir(DefId), | ||
/// Something went wrong in low-level compiler support. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence doesn't parse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean. Seems OK here.
Does "Something went wrong in the compiler's tracing code" work better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep!
One thing that might be worth thinking about is whether you want to |
A |
Works for me. |
Ah interesting. Remember what Jake showed us LLVM does? If a return value is larger than a register, it'll put it on the caller's stack and pass a reference into the callee. I'd have to check if we can make that happen from Rust, but that'd be more efficient than heap allocating. Thoughts before I investigate? |
I think it's worth investigating! I'd forgotten about that LLVM discovery. |
I'd like to pretend I can make that sense of that... but it's beyond me! |
The highlighted line of the right-hand side shows the LLVM IR for the call on line 15 of the Rust program on the left. You can see that the signature of
To:
So the storage for the return value is allocated on the stack before the call, and a reference is passed into the callee. The callee then populates the pre-allocated space with the (conceptual) return value. Very cool. |
Aha, I see! |
So now the question is, do we prefer to leave the return value unboxed (thus using stack allocation) or box it and use heap allocation? My gut says the former is more efficient because stack allocation amounts to only subtracting from the stack pointer, whereas heap allocation requires locating a spot large enough on the heap. Using the heap also contributes to memory fragmentation and I'd also guess has worse locality. Would you agree? |
Why don't you try on your example? My guess is that boxing it still transforms things into a parameter, at which point the boxing is largely pointless (unless the struct involved is really big -- at some point the waste of stack space must be a factor, but I doubt we're at that point). |
That's probably because you've got |
Yes, I'd expect the compiler to use the stack if the Ok case is larger than a register. Indeed:
|
And what do we learn about Boxing the error type? I suppose we shouldn't as it seems LLVM does a good job of optimising it if it gets big. Agree? |
Agreed. |
The last two small changes address the outstanding comments. |
Please squash. |
This makes crashes at least print some useful information instead of just telling us that a None was unwrapped. Also add a failing (but ignored for now) test which currently causes TraceInvalid::NoSir. This means we have encountered a location for which we have no SIR. A future PR will fix this, but first we will need some debugging aids before we can understand exactly what's gone wrong.
7792849
to
e192095
Compare
splat |
bors r+ |
21: An error type for trace invalidation. r=ltratt a=vext01 The meat of this PR is in the first commit (see the commit message for more) and then there's a boring style change. Co-authored-by: Edd Barrett <[email protected]>
Build succeeded |
…ril,gnzlbg Improve the documentation for std::hint::black_box. The other day a colleague was reviewing some of my code which was using `black_box` to block constant propogation. There was a little confusion because the documentation kind of implies that `black_box` is only useful for dead code elimination, and only in benchmarking scenarios. The docs currently say: > A function that is opaque to the optimizer, to allow benchmarks to pretend to use outputs to assist in avoiding dead-code elimination. Here is our discussion, in which I show (using godbolt) that a black box can also block constant propagation: ykjit/yk#21 (comment) This change makes the docstring for `black_box` a little more general, and while we are here, I've added an example (the same one from our discussion). ![image](https://user-images.githubusercontent.com/604955/61701322-ddf1e400-ad35-11e9-878c-b5b44a20770c.png) OK to go in?
21: Start documenting our approach to PRs. r=ptersilie a=ltratt Although our approach is heavily influenced by projects like Rust, it's sufficiently elaborate that newcomers find it difficult. This commit tries to capture both the process *and* the reasons for that process. It is necessarily incomplete and imperfect: I'm sure we'll need to iterate on this for a little while before we feel fully happy with it. However, this is a start -- something is better than nothing! Co-authored-by: Laurence Tratt <[email protected]>
The meat of this PR is in the first commit (see the commit message for more) and then there's a boring style change.