diff options
Diffstat (limited to 'compiler/rustc_mir_transform/src')
10 files changed, 37 insertions, 107 deletions
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 036b5589849..3d22035f078 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -10,16 +10,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; pub struct AddRetag; -/// Determines whether this place is "stable": Whether, if we evaluate it again -/// after the assignment, we can be sure to obtain the same place value. -/// (Concurrent accesses by other threads are no problem as these are anyway non-atomic -/// copies. Data races are UB.) -fn is_stable(place: PlaceRef<'_>) -> bool { - // Which place this evaluates to can change with any memory write, - // so cannot assume deref to be stable. - !place.has_deref() -} - /// Determine whether this type may contain a reference (or box), and thus needs retagging. /// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this. fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> bool { @@ -69,22 +59,10 @@ impl<'tcx> MirPass<'tcx> for AddRetag { let basic_blocks = body.basic_blocks.as_mut(); let local_decls = &body.local_decls; let needs_retag = |place: &Place<'tcx>| { - // FIXME: Instead of giving up for unstable places, we should introduce - // a temporary and retag on that. - is_stable(place.as_ref()) + !place.has_deref() // we're not eally interested in stores to "outside" locations, they are hard to keep track of anyway && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx) && !local_decls[place.local].is_deref_temp() }; - let place_base_raw = |place: &Place<'tcx>| { - // If this is a `Deref`, get the type of what we are deref'ing. - if place.has_deref() { - let ty = &local_decls[place.local].ty; - ty.is_unsafe_ptr() - } else { - // Not a deref, and thus not raw. - false - } - }; // PART 1 // Retag arguments at the beginning of the start block. @@ -108,7 +86,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag { } // PART 2 - // Retag return values of functions. Also escape-to-raw the argument of `drop`. + // Retag return values of functions. // We collect the return destinations because we cannot mutate while iterating. let returns = basic_blocks .iter_mut() @@ -140,30 +118,25 @@ impl<'tcx> MirPass<'tcx> for AddRetag { } // PART 3 - // Add retag after assignment. + // Add retag after assignments where data "enters" this function: the RHS is behind a deref and the LHS is not. for block_data in basic_blocks { // We want to insert statements as we iterate. To this end, we // iterate backwards using indices. for i in (0..block_data.statements.len()).rev() { let (retag_kind, place) = match block_data.statements[i].kind { - // Retag-as-raw after escaping to a raw pointer, if the referent - // is not already a raw pointer. - StatementKind::Assign(box (lplace, Rvalue::AddressOf(_, ref rplace))) - if !place_base_raw(rplace) => - { - (RetagKind::Raw, lplace) - } // Retag after assignments of reference type. StatementKind::Assign(box (ref place, ref rvalue)) if needs_retag(place) => { - let kind = match rvalue { - Rvalue::Ref(_, borrow_kind, _) - if borrow_kind.allows_two_phase_borrow() => - { - RetagKind::TwoPhase - } - _ => RetagKind::Default, + let add_retag = match rvalue { + // Ptr-creating operations already do their own internal retagging, no + // need to also add a retag statement. + Rvalue::Ref(..) | Rvalue::AddressOf(..) => false, + _ => true, }; - (kind, *place) + if add_retag { + (RetagKind::Default, *place) + } else { + continue; + } } // Do nothing for the rest _ => continue, diff --git a/compiler/rustc_mir_transform/src/const_goto.rs b/compiler/rustc_mir_transform/src/const_goto.rs index 0a305a40209..40eefda4f07 100644 --- a/compiler/rustc_mir_transform/src/const_goto.rs +++ b/compiler/rustc_mir_transform/src/const_goto.rs @@ -82,8 +82,9 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> { } let target_bb_terminator = target_bb.terminator(); - let (discr, switch_ty, targets) = target_bb_terminator.kind.as_switch()?; + let (discr, targets) = target_bb_terminator.kind.as_switch()?; if discr.place() == Some(*place) { + let switch_ty = place.ty(self.body.local_decls(), self.tcx).ty; // We now know that the Switch matches on the const place, and it is statementless // Now find which value in the Switch matches the const value. let const_value = diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 9c9ed5fa510..eba6a2b34e4 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -37,7 +37,7 @@ use rustc_data_structures::graph::WithSuccessors; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty; use rustc_span::{self, BytePos, Pos, Span, DUMMY_SP}; // All `TEMP_BLOCK` targets should be replaced before calling `to_body() -> mir::Body`. @@ -47,7 +47,6 @@ struct MockBlocks<'tcx> { blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>, dummy_place: Place<'tcx>, next_local: usize, - bool_ty: Ty<'tcx>, } impl<'tcx> MockBlocks<'tcx> { @@ -56,7 +55,6 @@ impl<'tcx> MockBlocks<'tcx> { blocks: IndexVec::new(), dummy_place: Place { local: RETURN_PLACE, projection: ty::List::empty() }, next_local: 0, - bool_ty: TyCtxt::BOOL_TY_FOR_UNIT_TESTING, } } @@ -157,7 +155,6 @@ impl<'tcx> MockBlocks<'tcx> { fn switchint(&mut self, some_from_block: Option<BasicBlock>) -> BasicBlock { let switchint_kind = TerminatorKind::SwitchInt { discr: Operand::Move(Place::from(self.new_temp())), - switch_ty: self.bool_ty, // just a dummy value targets: SwitchTargets::static_if(0, TEMP_BLOCK, TEMP_BLOCK), }; self.add_block_from(some_from_block, switchint_kind) diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index 32e738bbcea..8a7b027ddda 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -121,7 +121,6 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { let TerminatorKind::SwitchInt { discr: parent_op, - switch_ty: parent_ty, targets: parent_targets } = &bbs[parent].terminator().kind else { unreachable!() @@ -132,6 +131,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { Operand::Copy(x) => Operand::Copy(*x), Operand::Constant(x) => Operand::Constant(x.clone()), }; + let parent_ty = parent_op.ty(body.local_decls(), tcx); let statements_before = bbs[parent].statements.len(); let parent_end = Location { block: parent, statement_index: statements_before }; @@ -153,7 +153,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { // create temp to store inequality comparison between the two discriminants, `_t` in // example above let nequal = BinOp::Ne; - let comp_res_type = nequal.ty(tcx, *parent_ty, opt_data.child_ty); + let comp_res_type = nequal.ty(tcx, parent_ty, opt_data.child_ty); let comp_temp = patch.new_temp(comp_res_type, opt_data.child_source.span); patch.add_statement(parent_end, StatementKind::StorageLive(comp_temp)); @@ -181,7 +181,6 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { kind: TerminatorKind::SwitchInt { // switch on the first discriminant, so we can mark the second one as dead discr: parent_op, - switch_ty: opt_data.child_ty, targets: eq_targets, }, })); @@ -193,12 +192,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { let false_case = eq_bb; patch.patch_terminator( parent, - TerminatorKind::if_( - tcx, - Operand::Move(Place::from(comp_temp)), - true_case, - false_case, - ), + TerminatorKind::if_(Operand::Move(Place::from(comp_temp)), true_case, false_case), ); // generate StorageDead for the second_discriminant_temp not in use anymore @@ -319,11 +313,11 @@ fn evaluate_candidate<'tcx>( let bbs = &body.basic_blocks; let TerminatorKind::SwitchInt { targets, - switch_ty: parent_ty, - .. + discr: parent_discr, } = &bbs[parent].terminator().kind else { return None }; + let parent_ty = parent_discr.ty(body.local_decls(), tcx); let parent_dest = { let poss = targets.otherwise(); // If the fallthrough on the parent is trivially unreachable, we can let the @@ -339,12 +333,12 @@ fn evaluate_candidate<'tcx>( let (_, child) = targets.iter().next()?; let child_terminator = &bbs[child].terminator(); let TerminatorKind::SwitchInt { - switch_ty: child_ty, targets: child_targets, - .. + discr: child_discr, } = &child_terminator.kind else { return None }; + let child_ty = child_discr.ty(body.local_decls(), tcx); if child_ty != parent_ty { return None; } @@ -372,7 +366,7 @@ fn evaluate_candidate<'tcx>( Some(OptimizationData { destination, child_place: *child_place, - child_ty: *child_ty, + child_ty, child_source: child_terminator.source_info, }) } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 8922298ecaf..c08593afe9d 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -877,11 +877,7 @@ fn insert_switch<'tcx>( let (assign, discr) = transform.get_discr(body); let switch_targets = SwitchTargets::new(cases.iter().map(|(i, bb)| ((*i) as u128, *bb)), default_block); - let switch = TerminatorKind::SwitchInt { - discr: Operand::Move(discr), - switch_ty: transform.discr_ty, - targets: switch_targets, - }; + let switch = TerminatorKind::SwitchInt { discr: Operand::Move(discr), targets: switch_targets }; let source_info = SourceInfo::outermost(body.span); body.basic_blocks_mut().raw.insert( @@ -985,16 +981,6 @@ fn create_generator_drop_shim<'tcx>( tcx.mk_ptr(ty::TypeAndMut { ty: gen_ty, mutbl: hir::Mutability::Mut }), source_info, ); - if tcx.sess.opts.unstable_opts.mir_emit_retag { - // Alias tracking must know we changed the type - body.basic_blocks_mut()[START_BLOCK].statements.insert( - 0, - Statement { - source_info, - kind: StatementKind::Retag(RetagKind::Raw, Box::new(Place::from(SELF_ARG))), - }, - ) - } // Make sure we remove dead blocks to remove // unrelated code from the resume part of the function diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index a0ba69c89b0..ce05db5b762 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -55,10 +55,9 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { continue; } - let (discr, val, switch_ty, first, second) = match bbs[bb_idx].terminator().kind { + let (discr, val, first, second) = match bbs[bb_idx].terminator().kind { TerminatorKind::SwitchInt { discr: ref discr @ (Operand::Copy(_) | Operand::Move(_)), - switch_ty, ref targets, .. } if targets.iter().len() == 1 => { @@ -66,7 +65,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { if target == targets.otherwise() { continue; } - (discr, value, switch_ty, target, targets.otherwise()) + (discr, value, target, targets.otherwise()) } // Only optimize switch int statements _ => continue, @@ -105,10 +104,11 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { } // Take ownership of items now that we know we can optimize. let discr = discr.clone(); + let discr_ty = discr.ty(&body.local_decls, tcx); // Introduce a temporary for the discriminant value. let source_info = bbs[bb_idx].terminator().source_info; - let discr_local = body.local_decls.push(LocalDecl::new(switch_ty, source_info.span)); + let discr_local = body.local_decls.push(LocalDecl::new(discr_ty, source_info.span)); // We already checked that first and second are different blocks, // and bb_idx has a different terminator from both of them. @@ -130,10 +130,10 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { (*f).clone() } else { // Different value between blocks. Make value conditional on switch condition. - let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size; + let size = tcx.layout_of(param_env.and(discr_ty)).unwrap().size; let const_cmp = Operand::const_from_scalar( tcx, - switch_ty, + discr_ty, rustc_const_eval::interpret::Scalar::from_uint(val, size), rustc_span::DUMMY_SP, ); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index a115bb2831a..f92a0e826dc 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -177,16 +177,6 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) if ty.is_some() { // The first argument (index 0), but add 1 for the return value. let dropee_ptr = Place::from(Local::new(1 + 0)); - if tcx.sess.opts.unstable_opts.mir_emit_retag { - // Function arguments should be retagged, and we make this one raw. - body.basic_blocks_mut()[START_BLOCK].statements.insert( - 0, - Statement { - source_info, - kind: StatementKind::Retag(RetagKind::Raw, Box::new(dropee_ptr)), - }, - ); - } let patch = { let param_env = tcx.param_env_reveal_all_normalized(def_id); let mut elaborator = @@ -558,7 +548,6 @@ impl<'tcx> CloneShimBuilder<'tcx> { statements.push(statement); *kind = TerminatorKind::SwitchInt { discr: Operand::Move(temp), - switch_ty: discr_ty, targets: SwitchTargets::new(cases.into_iter(), unreachable), }; } diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index 405ebce4d22..8164b305278 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -24,12 +24,9 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { TerminatorKind::SwitchInt { - discr: Operand::Constant(ref c), - switch_ty, - ref targets, - .. + discr: Operand::Constant(ref c), ref targets, .. } => { - let constant = c.literal.try_eval_bits(tcx, param_env, switch_ty); + let constant = c.literal.try_eval_bits(tcx, param_env, c.ty()); if let Some(constant) = constant { let target = targets.target_for_value(constant); TerminatorKind::Goto { target } diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 321d8c63b6e..dcad1518eb6 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -127,11 +127,8 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral { let targets = SwitchTargets::new(iter::once((new_value, bb_cond)), bb_otherwise); let terminator = bb.terminator_mut(); - terminator.kind = TerminatorKind::SwitchInt { - discr: Operand::Move(opt.to_switch_on), - switch_ty: opt.branch_value_ty, - targets, - }; + terminator.kind = + TerminatorKind::SwitchInt { discr: Operand::Move(opt.to_switch_on), targets }; } for (idx, bb_idx) in storage_deads_to_remove { diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index 95fda2eafe8..06deca2fffb 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -76,7 +76,7 @@ where let terminator = match terminator_kind { // This will unconditionally run into an unreachable and is therefore unreachable as well. TerminatorKind::Goto { target } if is_unreachable(*target) => TerminatorKind::Unreachable, - TerminatorKind::SwitchInt { targets, discr, switch_ty } => { + TerminatorKind::SwitchInt { targets, discr } => { let otherwise = targets.otherwise(); // If all targets are unreachable, we can be unreachable as well. @@ -110,11 +110,7 @@ where return None; } - TerminatorKind::SwitchInt { - discr: discr.clone(), - switch_ty: *switch_ty, - targets: new_targets, - } + TerminatorKind::SwitchInt { discr: discr.clone(), targets: new_targets } } else { // If the otherwise branch is reachable, we don't want to delete any unreachable branches. return None; |
