summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_transform/src/lower_slice_len.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_transform/src/lower_slice_len.rs')
-rw-r--r--compiler/rustc_mir_transform/src/lower_slice_len.rs78
1 files changed, 27 insertions, 51 deletions
diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs
index b7cc0db95..ae4878411 100644
--- a/compiler/rustc_mir_transform/src/lower_slice_len.rs
+++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs
@@ -34,67 +34,43 @@ pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
}
}
-struct SliceLenPatchInformation<'tcx> {
- add_statement: Statement<'tcx>,
- new_terminator_kind: TerminatorKind<'tcx>,
-}
-
fn lower_slice_len_call<'tcx>(
tcx: TyCtxt<'tcx>,
block: &mut BasicBlockData<'tcx>,
local_decls: &IndexSlice<Local, LocalDecl<'tcx>>,
slice_len_fn_item_def_id: DefId,
) {
- let mut patch_found: Option<SliceLenPatchInformation<'_>> = None;
-
let terminator = block.terminator();
- match &terminator.kind {
- TerminatorKind::Call {
- func,
- args,
- destination,
- target: Some(bb),
- call_source: CallSource::Normal,
- ..
- } => {
- // some heuristics for fast rejection
- if args.len() != 1 {
- return;
- }
- let Some(arg) = args[0].place() else { return };
- let func_ty = func.ty(local_decls, tcx);
- match func_ty.kind() {
- ty::FnDef(fn_def_id, _) if fn_def_id == &slice_len_fn_item_def_id => {
- // perform modifications
- // from something like `_5 = core::slice::<impl [u8]>::len(move _6) -> bb1`
- // into:
- // ```
- // _5 = Len(*_6)
- // goto bb1
- // ```
+ if let TerminatorKind::Call {
+ func,
+ args,
+ destination,
+ target: Some(bb),
+ call_source: CallSource::Normal,
+ ..
+ } = &terminator.kind
+ // some heuristics for fast rejection
+ && let [arg] = &args[..]
+ && let Some(arg) = arg.place()
+ && let ty::FnDef(fn_def_id, _) = func.ty(local_decls, tcx).kind()
+ && *fn_def_id == slice_len_fn_item_def_id
+ {
+ // perform modifications from something like:
+ // _5 = core::slice::<impl [u8]>::len(move _6) -> bb1
+ // into:
+ // _5 = Len(*_6)
+ // goto bb1
- // make new RValue for Len
- let deref_arg = tcx.mk_place_deref(arg);
- let r_value = Rvalue::Len(deref_arg);
- let len_statement_kind =
- StatementKind::Assign(Box::new((*destination, r_value)));
- let add_statement =
- Statement { kind: len_statement_kind, source_info: terminator.source_info };
+ // make new RValue for Len
+ let deref_arg = tcx.mk_place_deref(arg);
+ let r_value = Rvalue::Len(deref_arg);
+ let len_statement_kind = StatementKind::Assign(Box::new((*destination, r_value)));
+ let add_statement =
+ Statement { kind: len_statement_kind, source_info: terminator.source_info };
- // modify terminator into simple Goto
- let new_terminator_kind = TerminatorKind::Goto { target: *bb };
-
- let patch = SliceLenPatchInformation { add_statement, new_terminator_kind };
-
- patch_found = Some(patch);
- }
- _ => {}
- }
- }
- _ => {}
- }
+ // modify terminator into simple Goto
+ let new_terminator_kind = TerminatorKind::Goto { target: *bb };
- if let Some(SliceLenPatchInformation { add_statement, new_terminator_kind }) = patch_found {
block.statements.push(add_statement);
block.terminator_mut().kind = new_terminator_kind;
}