From 899836306f65562912e36ace0631c46bb833db14 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Mon, 15 Mar 2021 21:57:52 -0400 Subject: [PATCH] remove assignments to ZST places --- .../rustc_mir/src/transform/instcombine.rs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/transform/instcombine.rs b/compiler/rustc_mir/src/transform/instcombine.rs index bad82fe893e..5ac2ff1fc9a 100644 --- a/compiler/rustc_mir/src/transform/instcombine.rs +++ b/compiler/rustc_mir/src/transform/instcombine.rs @@ -12,10 +12,12 @@ impl<'tcx> MirPass<'tcx> for InstCombine { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let param_env = tcx.param_env(body.source.def_id()); let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); - let ctx = InstCombineContext { tcx, local_decls }; + let ctx = InstCombineContext { tcx, local_decls, param_env }; for block in basic_blocks.iter_mut() { for statement in block.statements.iter_mut() { + ctx.combine_zst(&statement.source_info, &mut statement.kind); match statement.kind { StatementKind::Assign(box (_place, ref mut rvalue)) => { ctx.combine_bool_cmp(&statement.source_info, rvalue); @@ -32,6 +34,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { struct InstCombineContext<'tcx, 'a> { tcx: TyCtxt<'tcx>, local_decls: &'a LocalDecls<'tcx>, + param_env: ty::ParamEnv<'tcx>, } impl<'tcx, 'a> InstCombineContext<'tcx, 'a> { @@ -41,6 +44,28 @@ fn should_combine(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> boo }) } + /// Remove assignments to inhabited ZST places. + fn combine_zst(&self, source_info: &SourceInfo, kind: &mut StatementKind<'tcx>) { + match kind { + StatementKind::Assign(box (place, _)) => { + let place_ty = place.ty(self.local_decls, self.tcx).ty; + if let Ok(layout) = self.tcx.layout_of(self.param_env.and(place_ty)) { + if layout.is_zst() && !layout.abi.is_uninhabited() { + if self.tcx.consider_optimizing(|| { + format!( + "InstCombine ZST - Place: {:?} SourceInfo: {:?}", + place, source_info + ) + }) { + *kind = StatementKind::Nop; + } + } + } + } + _ => {} + } + } + /// Transform boolean comparisons into logical operations. fn combine_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { match rvalue {