Rollup merge of #94476 - c410-f3r:yet-more-let-chains, r=Dylan-DPC
7 - Make more use of `let_chains` Continuation of #94376. cc #53667
This commit is contained in:
commit
42596a71d6
@ -55,10 +55,8 @@ fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Consta
|
||||
|
||||
let mut locals_to_debuginfo = BitSet::new_empty(body.local_decls.len());
|
||||
for debuginfo in &body.var_debug_info {
|
||||
if let VarDebugInfoContents::Place(p) = debuginfo.value {
|
||||
if let Some(l) = p.as_local() {
|
||||
locals_to_debuginfo.insert(l);
|
||||
}
|
||||
if let VarDebugInfoContents::Place(p) = debuginfo.value && let Some(l) = p.as_local() {
|
||||
locals_to_debuginfo.insert(l);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,24 +633,22 @@ fn check_binary_op(
|
||||
fn propagate_operand(&mut self, operand: &mut Operand<'tcx>) {
|
||||
match *operand {
|
||||
Operand::Copy(l) | Operand::Move(l) => {
|
||||
if let Some(value) = self.get_const(l) {
|
||||
if self.should_const_prop(&value) {
|
||||
// FIXME(felix91gr): this code only handles `Scalar` cases.
|
||||
// For now, we're not handling `ScalarPair` cases because
|
||||
// doing so here would require a lot of code duplication.
|
||||
// We should hopefully generalize `Operand` handling into a fn,
|
||||
// and use it to do const-prop here and everywhere else
|
||||
// where it makes sense.
|
||||
if let interpret::Operand::Immediate(interpret::Immediate::Scalar(
|
||||
ScalarMaybeUninit::Scalar(scalar),
|
||||
)) = *value
|
||||
{
|
||||
*operand = self.operand_from_scalar(
|
||||
scalar,
|
||||
value.layout.ty,
|
||||
self.source_info.unwrap().span,
|
||||
);
|
||||
}
|
||||
if let Some(value) = self.get_const(l) && self.should_const_prop(&value) {
|
||||
// FIXME(felix91gr): this code only handles `Scalar` cases.
|
||||
// For now, we're not handling `ScalarPair` cases because
|
||||
// doing so here would require a lot of code duplication.
|
||||
// We should hopefully generalize `Operand` handling into a fn,
|
||||
// and use it to do const-prop here and everywhere else
|
||||
// where it makes sense.
|
||||
if let interpret::Operand::Immediate(interpret::Immediate::Scalar(
|
||||
ScalarMaybeUninit::Scalar(scalar),
|
||||
)) = *value
|
||||
{
|
||||
*operand = self.operand_from_scalar(
|
||||
scalar,
|
||||
value.layout.ty,
|
||||
self.source_info.unwrap().span,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1086,15 +1084,13 @@ fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Locatio
|
||||
// This will return None if the above `const_prop` invocation only "wrote" a
|
||||
// type whose creation requires no write. E.g. a generator whose initial state
|
||||
// consists solely of uninitialized memory (so it doesn't capture any locals).
|
||||
if let Some(ref value) = self.get_const(place) {
|
||||
if self.should_const_prop(value) {
|
||||
trace!("replacing {:?} with {:?}", rval, value);
|
||||
self.replace_with_const(rval, value, source_info);
|
||||
if can_const_prop == ConstPropMode::FullConstProp
|
||||
|| can_const_prop == ConstPropMode::OnlyInsideOwnBlock
|
||||
{
|
||||
trace!("propagated into {:?}", place);
|
||||
}
|
||||
if let Some(ref value) = self.get_const(place) && self.should_const_prop(value) {
|
||||
trace!("replacing {:?} with {:?}", rval, value);
|
||||
self.replace_with_const(rval, value, source_info);
|
||||
if can_const_prop == ConstPropMode::FullConstProp
|
||||
|| can_const_prop == ConstPropMode::OnlyInsideOwnBlock
|
||||
{
|
||||
trace!("propagated into {:?}", place);
|
||||
}
|
||||
}
|
||||
match can_const_prop {
|
||||
|
@ -357,14 +357,12 @@ fn format_operand(&self, operand: ExpressionOperandId) -> String {
|
||||
if let Some(counters) = &self.some_counters {
|
||||
if let Some(DebugCounter { counter_kind, some_block_label }) = counters.get(&operand) {
|
||||
if let CoverageKind::Expression { .. } = counter_kind {
|
||||
if let Some(block_label) = some_block_label {
|
||||
if debug_options().counter_format.block {
|
||||
return format!(
|
||||
"{}:({})",
|
||||
block_label,
|
||||
self.format_counter_kind(counter_kind)
|
||||
);
|
||||
}
|
||||
if let Some(label) = some_block_label && debug_options().counter_format.block {
|
||||
return format!(
|
||||
"{}:({})",
|
||||
label,
|
||||
self.format_counter_kind(counter_kind)
|
||||
);
|
||||
}
|
||||
return format!("({})", self.format_counter_kind(counter_kind));
|
||||
}
|
||||
|
@ -191,16 +191,13 @@ pub fn current_macro(&self) -> Option<Symbol> {
|
||||
/// If the span is part of a macro, and the macro is visible (expands directly to the given
|
||||
/// body_span), returns the macro name symbol.
|
||||
pub fn visible_macro(&self, body_span: Span) -> Option<Symbol> {
|
||||
if let Some(current_macro) = self.current_macro() {
|
||||
if self
|
||||
.expn_span
|
||||
.parent_callsite()
|
||||
.unwrap_or_else(|| bug!("macro must have a parent"))
|
||||
.ctxt()
|
||||
== body_span.ctxt()
|
||||
{
|
||||
return Some(current_macro);
|
||||
}
|
||||
if let Some(current_macro) = self.current_macro() && self
|
||||
.expn_span
|
||||
.parent_callsite()
|
||||
.unwrap_or_else(|| bug!("macro must have a parent"))
|
||||
.ctxt() == body_span.ctxt()
|
||||
{
|
||||
return Some(current_macro);
|
||||
}
|
||||
None
|
||||
}
|
||||
@ -584,21 +581,19 @@ fn take_prev(&mut self) -> CoverageSpan {
|
||||
/// In either case, no more spans will match the span of `pending_dups`, so
|
||||
/// add the `pending_dups` if they don't overlap `curr`, and clear the list.
|
||||
fn check_pending_dups(&mut self) {
|
||||
if let Some(dup) = self.pending_dups.last() {
|
||||
if dup.span != self.prev().span {
|
||||
debug!(
|
||||
" SAME spans, but pending_dups are NOT THE SAME, so BCBs matched on \
|
||||
previous iteration, or prev started a new disjoint span"
|
||||
);
|
||||
if dup.span.hi() <= self.curr().span.lo() {
|
||||
let pending_dups = self.pending_dups.split_off(0);
|
||||
for dup in pending_dups.into_iter() {
|
||||
debug!(" ...adding at least one pending={:?}", dup);
|
||||
self.push_refined_span(dup);
|
||||
}
|
||||
} else {
|
||||
self.pending_dups.clear();
|
||||
if let Some(dup) = self.pending_dups.last() && dup.span != self.prev().span {
|
||||
debug!(
|
||||
" SAME spans, but pending_dups are NOT THE SAME, so BCBs matched on \
|
||||
previous iteration, or prev started a new disjoint span"
|
||||
);
|
||||
if dup.span.hi() <= self.curr().span.lo() {
|
||||
let pending_dups = self.pending_dups.split_off(0);
|
||||
for dup in pending_dups.into_iter() {
|
||||
debug!(" ...adding at least one pending={:?}", dup);
|
||||
self.push_refined_span(dup);
|
||||
}
|
||||
} else {
|
||||
self.pending_dups.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -549,14 +549,15 @@ fn record_terminator_conflicts(&mut self, term: &Terminator<'_>) {
|
||||
target: _,
|
||||
unwind: _,
|
||||
} => {
|
||||
if let Some(place) = value.place() {
|
||||
if !place.is_indirect() && !dropped_place.is_indirect() {
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dropped_place.local,
|
||||
"DropAndReplace operand overlap",
|
||||
);
|
||||
}
|
||||
if let Some(place) = value.place()
|
||||
&& !place.is_indirect()
|
||||
&& !dropped_place.is_indirect()
|
||||
{
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dropped_place.local,
|
||||
"DropAndReplace operand overlap",
|
||||
);
|
||||
}
|
||||
}
|
||||
TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
|
||||
@ -614,14 +615,15 @@ fn record_terminator_conflicts(&mut self, term: &Terminator<'_>) {
|
||||
for op in operands {
|
||||
match op {
|
||||
InlineAsmOperand::In { reg: _, value } => {
|
||||
if let Some(p) = value.place() {
|
||||
if !p.is_indirect() && !dest_place.is_indirect() {
|
||||
self.record_local_conflict(
|
||||
p.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
if let Some(p) = value.place()
|
||||
&& !p.is_indirect()
|
||||
&& !dest_place.is_indirect()
|
||||
{
|
||||
self.record_local_conflict(
|
||||
p.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Out {
|
||||
@ -643,24 +645,26 @@ fn record_terminator_conflicts(&mut self, term: &Terminator<'_>) {
|
||||
in_value,
|
||||
out_place,
|
||||
} => {
|
||||
if let Some(place) = in_value.place() {
|
||||
if !place.is_indirect() && !dest_place.is_indirect() {
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
if let Some(place) = in_value.place()
|
||||
&& !place.is_indirect()
|
||||
&& !dest_place.is_indirect()
|
||||
{
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(place) = out_place {
|
||||
if !place.is_indirect() && !dest_place.is_indirect() {
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
if let Some(place) = out_place
|
||||
&& !place.is_indirect()
|
||||
&& !dest_place.is_indirect()
|
||||
{
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Out { reg: _, late: _, place: None }
|
||||
|
@ -724,12 +724,11 @@ fn create_temp_if_necessary(
|
||||
caller_body: &mut Body<'tcx>,
|
||||
) -> Local {
|
||||
// Reuse the operand if it is a moved temporary.
|
||||
if let Operand::Move(place) = &arg {
|
||||
if let Some(local) = place.as_local() {
|
||||
if caller_body.local_kind(local) == LocalKind::Temp {
|
||||
return local;
|
||||
}
|
||||
}
|
||||
if let Operand::Move(place) = &arg
|
||||
&& let Some(local) = place.as_local()
|
||||
&& caller_body.local_kind(local) == LocalKind::Temp
|
||||
{
|
||||
return local;
|
||||
}
|
||||
|
||||
// Otherwise, create a temporary for the argument.
|
||||
|
@ -77,10 +77,8 @@ fn combine_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>)
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(new) = new {
|
||||
if self.should_combine(source_info, rvalue) {
|
||||
*rvalue = new;
|
||||
}
|
||||
if let Some(new) = new && self.should_combine(source_info, rvalue) {
|
||||
*rvalue = new;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,17 @@
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(map_try_insert)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(option_get_or_insert_default)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(never_type)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(option_get_or_insert_default)]
|
||||
#![feature(trusted_step)]
|
||||
#![feature(try_blocks)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
@ -14,10 +14,9 @@ pub fn new(required_consts: &'a mut Vec<Constant<'tcx>>) -> Self {
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
|
||||
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
|
||||
if let Some(ct) = constant.literal.const_for_ty() {
|
||||
if let ConstKind::Unevaluated(_) = ct.val() {
|
||||
self.required_consts.push(*constant);
|
||||
}
|
||||
let literal = constant.literal;
|
||||
if let Some(ct) = literal.const_for_ty() && let ConstKind::Unevaluated(_) = ct.val() {
|
||||
self.required_consts.push(*constant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user