-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Transforms match into an assignment statement #120614
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
Changes from 1 commit
badb73b
7af7458
1f061f4
e752af7
254289a
032bb74
f440737
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…tement as well
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,6 +1,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use rustc_index::IndexVec; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use rustc_middle::mir::*; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use rustc_middle::ty::{ParamEnv, ScalarInt, Ty, TyCtxt}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use rustc_target::abi::Size; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::iter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use super::simplify::simplify_cfg; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -67,13 +68,13 @@ trait SimplifyMatch<'tcx> { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_ => unreachable!(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if !self.can_simplify(tcx, targets, param_env, bbs) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let discr_ty = discr.ty(local_decls, tcx); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if !self.can_simplify(tcx, targets, param_env, bbs, discr_ty) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Take ownership of items now that we know we can optimize. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let discr = discr.clone(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let discr_ty = discr.ty(local_decls, tcx); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Introduce a temporary for the discriminant value. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let source_info = bbs[switch_bb_idx].terminator().source_info; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -104,6 +105,7 @@ trait SimplifyMatch<'tcx> { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
targets: &SwitchTargets, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
param_env: ParamEnv<'tcx>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bbs: &IndexVec<BasicBlock, BasicBlockData<'tcx>>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
discr_ty: Ty<'tcx>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> bool; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fn new_stmts( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -157,6 +159,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
targets: &SwitchTargets, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
param_env: ParamEnv<'tcx>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bbs: &IndexVec<BasicBlock, BasicBlockData<'tcx>>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_discr_ty: Ty<'tcx>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if targets.iter().len() != 1 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -268,7 +271,7 @@ struct SimplifyToExp { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum CompareType<'tcx, 'a> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Same(&'a StatementKind<'tcx>), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Eq(&'a Place<'tcx>, Ty<'tcx>, ScalarInt), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Discr(&'a Place<'tcx>, Ty<'tcx>), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Discr(&'a Place<'tcx>, Ty<'tcx>, bool), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
enum TransfromType { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -282,7 +285,7 @@ impl From<CompareType<'_, '_>> for TransfromType { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
match compare_type { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CompareType::Same(_) => TransfromType::Same, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CompareType::Eq(_, _, _) => TransfromType::Eq, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CompareType::Discr(_, _) => TransfromType::Discr, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CompareType::Discr(_, _, _) => TransfromType::Discr, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -333,6 +336,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
targets: &SwitchTargets, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
param_env: ParamEnv<'tcx>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bbs: &IndexVec<BasicBlock, BasicBlockData<'tcx>>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
discr_ty: Ty<'tcx>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Code readability idea: would it simplify anything to return an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm using it in the wrong way. I didn't feel the improvement. Maybe because there is not |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if targets.iter().len() < 2 || targets.iter().len() > 64 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -355,13 +359,19 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let discr_size = tcx.layout_of(param_env.and(discr_ty)).unwrap().size; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let first_stmts = &bbs[first_target].statements; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let (second_val, second_target) = target_iter.next().unwrap(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let second_stmts = &bbs[second_target].statements; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if first_stmts.len() != second_stmts.len() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fn int_equal(l: ScalarInt, r: impl Into<u128>, size: Size) -> bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
l.try_to_int(l.size()).unwrap() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
== ScalarInt::try_from_uint(r, size).unwrap().try_to_int(size).unwrap() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the point of doing the comparison in such a complicated way? Why turn There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't need the sign, as I said: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, you're right. This code is used to compare signed integers of different widths, such as |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut compare_types = Vec::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (f, s) in iter::zip(first_stmts, second_stmts) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let compare_type = match (&f.kind, &s.kind) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -382,12 +392,22 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(Some(f), Some(s)) if f == s => CompareType::Eq(lhs_f, f_c.const_.ty(), f), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(Some(f), Some(s)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This branch definitely needs a comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added. The main thing here is to deal with the various enum variants. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if Some(f) == ScalarInt::try_from_uint(first_val, f.size()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& Some(s) == ScalarInt::try_from_uint(second_val, s.size()) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ((f_c.const_.ty().is_signed() || discr_ty.is_signed()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& int_equal(f, first_val, discr_size) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& int_equal(s, second_val, discr_size)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|| (Some(f) == ScalarInt::try_from_uint(first_val, f.size()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& Some(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
== ScalarInt::try_from_uint(second_val, s.size())) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is very strange. What is going on here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is used to handle conversions such as from rust/tests/mir-opt/matches_reduce_branches.rs Lines 69 to 85 in e752af7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aha... I have no idea what this means. ;) But it makes no sense to compare things twice here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above (different width), corresponding test case: rust/tests/mir-opt/matches_reduce_branches.rs Lines 197 to 215 in e752af7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But you are comparing both signed and unsigned representation completely disregarding whether the value is actually signed or unsigned. It sounds like you want two cases
But currently you're interpreting the number both ways and then checking if either comparison succeeds. It seems to me that can sometimes lead to blatantly wrong results, e.g. when two numbers are equal unsigned but different after sign extension, and they are actually signed -- you code will treat them as equal, I think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I'm fixing it right now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in #124122, thanks for pointing it out. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CompareType::Discr(lhs_f, f_c.const_.ty()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CompareType::Discr( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
lhs_f, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
f_c.const_.ty(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
f_c.const_.ty().is_signed() || discr_ty.is_signed(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_ => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_ => return false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -413,15 +433,22 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& s_c.const_.ty() == f_ty | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& s_c.const_.try_eval_scalar_int(tcx, param_env) == Some(val) => {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CompareType::Discr(lhs_f, f_ty), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CompareType::Discr(lhs_f, f_ty, is_signed), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) if lhs_f == lhs_s && s_c.const_.ty() == f_ty => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let Some(f) = s_c.const_.try_eval_scalar_int(tcx, param_env) else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if Some(f) != ScalarInt::try_from_uint(other_val, f.size()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if is_signed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& s_c.const_.ty().is_signed() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& int_equal(f, other_val, discr_size) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if Some(f) == ScalarInt::try_from_uint(other_val, f.size()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_ => return false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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.
Could you comment the 3 variants?
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.
Added. I've also updated
Discr
. But I'm not sure the current comments are clear enough.