about summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Desjardins <erikdesjardins@users.noreply.github.com>2021-03-15 21:57:52 -0400
committerErik Desjardins <erikdesjardins@users.noreply.github.com>2021-03-15 21:57:52 -0400
commit899836306f65562912e36ace0631c46bb833db14 (patch)
tree6f5da8f4df515e27de240b9c89ddfab1b3b2820f
parentaffb081fa0810494165fbfb8d308a0f02a290fed (diff)
remove assignments to ZST places
-rw-r--r--compiler/rustc_mir/src/transform/instcombine.rs27
1 files changed, 26 insertions, 1 deletions
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 @@ pub struct InstCombine;
 
 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 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
 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 @@ impl<'tcx, 'a> InstCombineContext<'tcx, 'a> {
         })
     }
 
+    /// 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 {