-
Notifications
You must be signed in to change notification settings - Fork 13k
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
CTFE engine refactor #53424
CTFE engine refactor #53424
Conversation
|
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
3f349b4
to
af45af7
Compare
We'll want a perf run. @bors try |
🔒 Merge conflict This pull request and the master branch diverged in a way that cannot be automatically merged. Please rebase on top of the latest master branch, and let the reviewer approve again. How do I rebase?Assuming
You may also read Git Rebasing to Resolve Conflicts by Drew Blessing for a short tutorial. Please avoid the "Resolve conflicts" button on GitHub. It uses Sometimes step 4 will complete without asking for resolution. This is usually due to difference between how Error message
|
Hu? I rebased right before I submitted this... |
af45af7
to
2d1134d
Compare
@bors try |
⌛ Trying commit 2d1134d1ee313cd422bb4767d000cb4e727e87e7 with merge b7e59799d3969b8df886349ed1a3c7ae38c1e57a... |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
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 refactoring was very overdue. Thanks so much for doing it. So many great things in there.
self.memory.check_align(ptr, ptr_align)?; | ||
|
||
if mplace.layout.size.bytes() == 0 { | ||
return Ok(Some(Value::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits { bits: 0, size: 0 })))); |
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.
use Scalar::zst()
. Maybe even Scalar::zst().into()
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.
Done.
// This decides which types we will use the Immediate optimization for, and hence should | ||
// match what `try_read_value` and `eval_place_to_op` support. | ||
if layout.is_zst() { | ||
return Ok(Operand::Immediate(Value::Scalar(ScalarMaybeUndef::Undef))); |
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 feels very odd. We have an undefined ZST?
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.
Well, why not?
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.
Okay I will just use Scalar::zst()
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.
What made you change your mind?
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.
Talking with @eddyb :D And also thinking about what this even means... I mean, ZSTs don't really have a value. The read functions short-circuit them before we even hit memory, and they always return Scalar::zst()
. So this seems more consistent.
Also, 0 bytes of unintiailized memory are not really undef
. They are just empty. As in, if you think of a value as a &[Byte]
, where Byte
is either u8
or Undef
-- then a value of size 0 cannot be Undef
.
layout::FieldPlacement::Array { count, .. } => count, | ||
_ => bug!("Length for non-array layout {:?} requested", self.layout), | ||
}; | ||
if let PlaceExtra::Length(len) = self.extra { |
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.
Why would an array ever have this? or do slices have Array
field layout, too?
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 was thinking so... @eddyb should know.^^ What is the layout of [u8]
?
I seem to remember it is an "array" of length 0.
self.layout.ty.hash(state); | ||
} | ||
} | ||
impl<'tcx> PartialEq for MPlaceTy<'tcx> { |
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.
can't this be derived?
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.
No, TyLayout
has no PartialEq
. So we just compare the type.
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 might want to include a few more things in the Eq/Hash, such as an Option<usize>
where Some(index)
means Variants::Single { index }
, while None
is for all other Variants
.
src/librustc_mir/interpret/place.rs
Outdated
pub fn write_value( | ||
&mut self, | ||
src_val: Value, | ||
dest : PlaceTy<'tcx>, |
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.
space after dest
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.
Fixed.
src/test/ui/union-ub-fat-ptr.rs
Outdated
const B2: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice}; | ||
//~^ ERROR this constant likely exhibits undefined behavior | ||
// bad | ||
const C2: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice}; | ||
//~^ ERROR this constant likely exhibits undefined behavior |
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.
can you also add a test where a trait object has the correct vtable and pointer but the object is wrong? So create the object unsafely with brokenness and then downcast
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 added these:
// bad data *inside* the trait object
const G: &Trait = &unsafe { BoolTransmute { val: 3 }.bl };
// bad data *inside* the slice
const H: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
Does that look like it is testing the right thing?
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 forgot to push, but assuming that bool: Trait
it should
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.
No I just waited for --bless
to finish before pushing. ;)
☀️ Test successful - status-travis |
Okay we don't need a perf run yet... triggered by a warning that some test takes >60s, I benchmarked |
Uh. Perf says
However, I also have debug-assertions enabled, so let's see if that makes a difference. |
After compiling without debug assertions, it's still 50% slower. |
d3b20ad
to
7066438
Compare
r=me w/o perf regressions and a crater run |
Didn't you suggest we should make a crater run as well? |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
I guess we do not have to wait with the crater run until I completed the perf work... @bors try |
🔒 Merge conflict This pull request and the master branch diverged in a way that cannot be automatically merged. Please rebase on top of the latest master branch, and let the reviewer approve again. How do I rebase?Assuming
You may also read Git Rebasing to Resolve Conflicts by Drew Blessing for a short tutorial. Please avoid the "Resolve conflicts" button on GitHub. It uses Sometimes step 4 will complete without asking for resolution. This is usually due to difference between how Error message
|
Argh.^^ Okay, another rebase... |
c4b2a17
to
6cf4d70
Compare
4038124
to
4fec615
Compare
This now does not update the submodule anymore. The submodule update will come in a separate PR. @bors r+ |
📌 Commit 4fec615 has been approved by |
CTFE engine refactor * Value gets renamed to `Operand`, so that now `interpret::{Place, Operand}` are the "dynamic" versions of `mir::{Place, Operand}`. * `Operand` and `Place` share the data for their "stuff is in memory"-base in a new type, `MemPlace`. This also makes it possible to give some more precise types in other areas. Both `Operand` and `MemPlace` have methods available to project into fields (and other kinds of projections) without causing further allocations. * The type for "a `Scalar` or a `ScalarPair`" is called `Value`, and again used to give some more precise types. * All of these have versions with an attached layout, so that we can more often drag the layout along instead of recomputing it. This lets us get rid of `PlaceExtra::Downcast`. `MPlaceTy` and `PlaceTy` can only be constructed in place.rs, making sure the layout is handled properly. (The same should eventually be done for `ValTy` and `OpTy`.) This is used to check, when copying an operand to a place, that the sizes match (which caught a bunch of bugs). * All the high-level functions to write typed memory take a `Place`, and live in `place.rs`. All the high-level typed functions to read typed memory take an `Operand`, and live in `operands.rs`. * Remove `cur_frame` and handling of signedess from memory (catching a bug in the float casting code). * [Only functional change] Enable sanity check to recurse below dyn traits and slices. r? @oli-obk Cc @eddyb
☀️ Test successful - status-appveyor, status-travis |
fix array drop glue: properly turn raw ptr into reference Discovered while working on #53424: The generated drop glue uses an assignment `ptr = cur` where `ptr` is a reference and `cur` a raw pointer. This is not well-formed MIR. Do we have MIR sanity checks that run on the drop glue and should have caught this? r? @eddyb
This PR is helping fixing #52849. Since that's a beta regression, should this be backported @rust-lang/compiler? |
I think this PR is way too big to be backported. If need be we can disable validation on beta. |
in the discussion on #52849, it sounds like one of the big performance issues came from hashing the memory state, which was then something that the discussion talked about removing. Was hashing the memory state actually removed (I cannot tell from skimming the titles of the commit series) on this PR (#53424)? And if it was the case, can that part of the diff be backported on its own? |
No it has not been removed here, but it will be removed in #52626. And yes, just removing it from the hash is trivial to backport. Do you want me to do that? |
Yes and no. The majority of that issue is fully intentional -- we walk the resulting value computed for every constant; in benchmarks that consist only of a single constant, that has a huge impact. Two unintentional changes that are also part of the same issue (hence the rather messy overall situation) are:
|
Operand
, so that nowinterpret::{Place, Operand}
are the "dynamic" versions ofmir::{Place, Operand}
.Operand
andPlace
share the data for their "stuff is in memory"-base in a new type,MemPlace
. This also makes it possible to give some more precise types in other areas. BothOperand
andMemPlace
have methods available to project into fields (and other kinds of projections) without causing further allocations.Scalar
or aScalarPair
" is calledValue
, and again used to give some more precise types.PlaceExtra::Downcast
.MPlaceTy
andPlaceTy
can only be constructed in place.rs, making sure the layout is handled properly. (The same should eventually be done forValTy
andOpTy
.)This is used to check, when copying an operand to a place, that the sizes match (which caught a bunch of bugs).
Place
, and live inplace.rs
. All the high-level typed functions to read typed memory take anOperand
, and live inoperands.rs
.cur_frame
and handling of signedess from memory (catching a bug in the float casting code).r? @oli-obk
Cc @eddyb