Skip to content
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

Add new MIR constant propagation based on dataflow analysis #101168

Merged
merged 76 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
4f9c30f
Add initial version of value analysis and dataflow constant propagation
jachris Aug 25, 2022
d0afe68
Try field type normalization instead of forcing it
jachris Aug 29, 2022
601fcc4
Update test results
jachris Aug 29, 2022
56ff16d
Fix spelling
jachris Aug 29, 2022
93ee806
Update test results
jachris Aug 29, 2022
c83489c
Remove empty test
jachris Aug 30, 2022
bb16397
Clarify registration and tracking of references
jachris Aug 30, 2022
2928694
Add additional flooding when assigning a value and corresponding test
jachris Aug 31, 2022
e75ad93
Begin a semi-formal argument for correctness
jachris Aug 31, 2022
1da3033
Change test from usize to i32 to prevent target issues
jachris Aug 31, 2022
3f98dc7
Clarify place expressions vs place objects
jachris Sep 1, 2022
ad99d2e
Move handling of references and simplify flooding
jachris Sep 1, 2022
47a00d5
Flood with bottom instead of top for unreachable branches
jachris Sep 1, 2022
8a789ce
Reject registration of downcasts for now
jachris Sep 1, 2022
469fb19
Update other test results
jachris Sep 1, 2022
16dedba
Ignore terminators explicitly
jachris Sep 1, 2022
fe84bbf
Add tracking of unreachability
jachris Sep 2, 2022
f234419
Rebase onto master
jachris Sep 2, 2022
895181b
Remove leftover test files
jachris Sep 2, 2022
2e4d082
Add more documentation
jachris Sep 2, 2022
2113e45
Remove superfluous line
jachris Sep 2, 2022
904adca
Flood place on drop
jachris Sep 4, 2022
1e5ca57
Use StorageDead and Deinit to flood place
jachris Sep 4, 2022
e2ddf8a
Add comment about downcast projection element
jachris Sep 4, 2022
817c277
Handle StorageLive
jachris Sep 9, 2022
bc82c13
Track Scalar instead of ScalarInt for const prop
jachris Sep 23, 2022
13b7059
Only allow registration of scalars for now
jachris Sep 27, 2022
6868617
Add tests from current const prop
jachris Sep 27, 2022
4cda6e5
Update test results
jachris Sep 27, 2022
97a69a7
Add some more unit-test directives
jachris Sep 27, 2022
c56e99c
Fix typo
jachris Sep 27, 2022
f99950f
Update test results after rebase
jachris Oct 4, 2022
eab7732
Handle NonDivergingIntrinsic and CopyNonOverlapping
jachris Oct 5, 2022
2f66e94
Flood with bottom for Deinit, StorageLive and StorageDead
jachris Oct 5, 2022
b5063ab
Make more assumptions explicit
jachris Oct 5, 2022
1765587
Only track (trivially) freeze types
jachris Oct 5, 2022
7ab1ba9
Remove `Unknown` state in favor of `Value(Top)`
jachris Oct 5, 2022
4478a87
Fix formatting
jachris Oct 5, 2022
111324e
Prevent registration inside references if target is !Freeze
jachris Oct 6, 2022
3c0f3b0
Only assume Stacked Borrows if -Zunsound-mir-opts is given
jachris Oct 6, 2022
7a52e73
Add tests for Stacked Borrows behavior
jachris Oct 6, 2022
b9dbb81
Improve example used for SB tests
jachris Oct 6, 2022
5696d06
Use the same is_enabled as the current const prop
jachris Oct 6, 2022
aaa35b3
Add comment for the current retag situation
jachris Oct 12, 2022
890fae9
Fix rebased CastKind
jachris Oct 12, 2022
8bed0b5
Update issue-50814.rs test result
jachris Oct 15, 2022
1dde908
Update test results
jachris Oct 15, 2022
be9013f
Make overflow flag propagation conditional
jachris Oct 15, 2022
931d99f
Make overflow handling more precise
jachris Oct 15, 2022
274a491
Improve documentation, plus some small changes
jachris Oct 19, 2022
062053b
Fix unimplemented binary_ptr_op
jachris Oct 19, 2022
5b7b309
Improve documentation of assumptions
jachris Oct 21, 2022
d86acdd
Prevent propagation of overflow if overflow occured
jachris Oct 23, 2022
de69d08
Explicitly match all terminators
jachris Oct 23, 2022
efc7ca8
Use ParamEnv consistently
jachris Oct 23, 2022
f29533b
Small documentation changes
jachris Oct 24, 2022
1f82a9f
Move HasTop and HasBottom into lattice.rs
jachris Oct 24, 2022
da4a40f
Remove copy of current const prop tests and add a few new tests
jachris Oct 25, 2022
630e17d
Limit number of tracked places, and some other perf improvements
jachris Oct 25, 2022
b478fcf
Use new cast methods
jachris Oct 26, 2022
72196ee
Limit number of basic blocks and tracked places to 100 for now
jachris Oct 27, 2022
89f9349
Small corrections of documentation
jachris Nov 7, 2022
3997893
Fix rebase
jachris Nov 7, 2022
bfbca6c
Completely remove tracking of references for now
jachris Nov 9, 2022
9766ee0
Fix struct field tracking and add tests for it
jachris Nov 9, 2022
8ecb276
Simplify creation of map
jachris Nov 10, 2022
3c6d1a7
Add test for repr(transparent) with scalar
jachris Nov 11, 2022
b3f6489
Add comment for guessed constants
jachris Nov 12, 2022
2e034dc
Exclude locals completely, instead of individual places
jachris Nov 12, 2022
74d53ab
Require -Zmir-opt-level >= 3 for now
jachris Nov 12, 2022
abe31a9
Partially revert 74d53ab
jachris Nov 12, 2022
d66a00a
Expand upon comment regarding self-assignment
jachris Nov 12, 2022
ea23585
Disable limits if mir-opt-level >= 4
jachris Nov 12, 2022
108790b
Remove log statement that was commented out
jachris Nov 12, 2022
c27ddc9
Remove redundant graphviz escaping
jachris Nov 14, 2022
24d2e90
Bless graphviz tests
jachris Nov 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler/rustc_graphviz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,11 @@ pub trait Labeller<'a> {
/// Escape tags in such a way that it is suitable for inclusion in a
/// Graphviz HTML label.
pub fn escape_html(s: &str) -> String {
s.replace('&', "&amp;").replace('\"', "&quot;").replace('<', "&lt;").replace('>', "&gt;")
s.replace('&', "&amp;")
.replace('\"', "&quot;")
.replace('<', "&lt;")
.replace('>', "&gt;")
.replace('\n', "<br align=\"left\"/>")
}

impl<'a> LabelText<'a> {
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_middle/src/mir/generic_graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl<
write!(
w,
r#"<tr><td align="left" balign="left">{}</td></tr>"#,
dot::escape_html(&section).replace('\n', "<br/>")
dot::escape_html(&section)
)?;
}

Expand All @@ -147,7 +147,7 @@ impl<
let src = self.node(source);
let trg = self.node(target);
let escaped_edge_label = if let Some(edge_label) = edge_labels.get(index) {
dot::escape_html(edge_label).replace('\n', r#"<br align="left"/>"#)
dot::escape_html(edge_label)
} else {
"".to_owned()
};
Expand All @@ -162,8 +162,7 @@ impl<
where
W: Write,
{
let lines = label.split('\n').map(|s| dot::escape_html(s)).collect::<Vec<_>>();
let escaped_label = lines.join(r#"<br align="left"/>"#);
let escaped_label = dot::escape_html(label);
writeln!(w, r#" label=<<br/><br/>{}<br align="left"/><br/><br/><br/>>;"#, escaped_label)
}

Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_middle/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,15 @@ impl PlaceContext {
)
}

/// Returns `true` if this place context represents an address-of.
pub fn is_address_of(&self) -> bool {
matches!(
self,
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
| PlaceContext::MutatingUse(MutatingUseContext::AddressOf)
)
}

/// Returns `true` if this place context represents a storage live or storage dead marker.
#[inline]
pub fn is_storage_marker(&self) -> bool {
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_mir_dataflow/src/framework/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,10 @@ where
r#"<td colspan="{colspan}" {fmt} align="left">{state}</td>"#,
colspan = this.style.num_state_columns(),
fmt = fmt,
state = format!("{:?}", DebugWithAdapter { this: state, ctxt: analysis }),
state = dot::escape_html(&format!(
"{:?}",
DebugWithAdapter { this: state, ctxt: analysis }
)),
)
})
}
Expand Down
34 changes: 34 additions & 0 deletions compiler/rustc_mir_dataflow/src/framework/lattice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ pub trait MeetSemiLattice: Eq {
fn meet(&mut self, other: &Self) -> bool;
}

/// A set that has a "bottom" element, which is less than or equal to any other element.
pub trait HasBottom {
fn bottom() -> Self;
}

/// A set that has a "top" element, which is greater than or equal to any other element.
pub trait HasTop {
fn top() -> Self;
}

/// A `bool` is a "two-point" lattice with `true` as the top element and `false` as the bottom:
///
/// ```text
Expand Down Expand Up @@ -102,6 +112,18 @@ impl MeetSemiLattice for bool {
}
}

impl HasBottom for bool {
fn bottom() -> Self {
false
}
}

impl HasTop for bool {
fn top() -> Self {
true
}
}

/// A tuple (or list) of lattices is itself a lattice whose least upper bound is the concatenation
/// of the least upper bounds of each element of the tuple (or list).
///
Expand Down Expand Up @@ -250,3 +272,15 @@ impl<T: Clone + Eq> MeetSemiLattice for FlatSet<T> {
true
}
}

impl<T> HasBottom for FlatSet<T> {
fn bottom() -> Self {
Self::Bottom
}
}

impl<T> HasTop for FlatSet<T> {
fn top() -> Self {
Self::Top
}
}
1 change: 1 addition & 0 deletions compiler/rustc_mir_dataflow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub mod move_paths;
pub mod rustc_peek;
pub mod storage;
pub mod un_derefer;
pub mod value_analysis;

pub(crate) mod indexes {
pub(crate) use super::move_paths::MovePathIndex;
Expand Down
Loading