about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2018-01-29 08:50:47 +0100
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2018-03-08 08:34:13 +0100
commit00c95b29bce5a6aa0acb10f78418760d5249394a (patch)
tree52016d6871f6aa5871da999441032c5d8d1ad561
parent54615ec9894f4f101bb15d70b6dc9b0c61f1249c (diff)
downloadrust-00c95b29bce5a6aa0acb10f78418760d5249394a.tar.gz
rust-00c95b29bce5a6aa0acb10f78418760d5249394a.zip
Revert all changes to the instcombine pass
-rw-r--r--src/librustc/ty/error.rs2
-rw-r--r--src/librustc_mir/transform/const_prop.rs83
-rw-r--r--src/librustc_mir/transform/instcombine.rs15
3 files changed, 77 insertions, 23 deletions
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index b50b9cb43d3..dcb70a8f86a 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -184,7 +184,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
             ty::TyArray(_, n) => {
                 match n.val.to_raw_bits() {
                     Some(n) => format!("array of {} elements", n),
-                    _ => "array".to_string(),
+                    None => "array".to_string(),
                 }
             }
             ty::TySlice(_) => "slice".to_string(),
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 652b921e80a..8cbb2afae39 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -44,8 +44,11 @@ impl MirPass for ConstProp {
             optimization_finder.optimizations
         };
 
-        // Then carry out those optimizations.
-        MutVisitor::visit_mir(&mut ConstPropVisitor { optimizations, tcx }, mir);
+        // We only actually run when optimizing MIR (at any level).
+        if tcx.sess.opts.debugging_opts.mir_opt_level != 0 {
+            // Then carry out those optimizations.
+            MutVisitor::visit_mir(&mut ConstPropVisitor { optimizations, tcx }, mir);
+        }
         trace!("ConstProp done for {:?}", source.def_id);
     }
 }
@@ -236,16 +239,6 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
         }
     }
 
-    fn simplify_operand(&mut self, op: &Operand<'tcx>) -> Option<Const<'tcx>> {
-        match *op {
-            Operand::Constant(ref c) => match c.literal {
-                Literal::Value { .. } => None,
-                _ => self.eval_operand(op),
-            },
-            _ => self.eval_operand(op),
-        }
-    }
-
     fn const_prop(
         &mut self,
         rvalue: &Rvalue<'tcx>,
@@ -487,14 +480,76 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
         &mut self,
         block: BasicBlock,
         kind: &TerminatorKind<'tcx>,
-        _location: Location,
+        location: Location,
     ) {
         match kind {
             TerminatorKind::SwitchInt { discr: value, .. } |
             TerminatorKind::Yield { value, .. } |
             TerminatorKind::Assert { cond: value, .. } => {
-                if let Some(value) = self.simplify_operand(value) {
+                match value {
+                    Operand::Constant(box Constant {
+                        literal: Literal::Value {
+                            value: &ty::Const {
+                                val: ConstVal::Value(_),
+                                ..
+                            },
+                        },
+                        ..
+                    }) => return,
+                    _ => {},
+                }
+                if let Some(value) = self.eval_operand(value) {
                     self.optimizations.terminators.insert(block, value);
+                    if let TerminatorKind::Assert { expected, msg, .. } = kind {
+                        if Value::ByVal(PrimVal::from_bool(*expected)) != value.0 {
+                            let span = self.mir[block]
+                                .statements[location.statement_index]
+                                .source_info
+                                .span;
+                            let node_id = self
+                                .tcx
+                                .hir
+                                .as_local_node_id(self.source.def_id)
+                                .expect("some part of a failing const eval must be local");
+                            let mut lint = self.tcx.struct_span_lint_node(
+                                ::rustc::lint::builtin::CONST_ERR,
+                                node_id,
+                                span,
+                                "constant evaluation error",
+                            );
+                            use rustc::mir::AssertMessage::*;
+                            match msg {
+                                GeneratorResumedAfterReturn =>
+                                    lint.span_label(span, "generator resumed after completion"),
+                                GeneratorResumedAfterPanic =>
+                                    lint.span_label(span, "generator resumed after panicking"),
+                                Math(ref err) => lint.span_label(span, err.description()),
+                                BoundsCheck { ref len, ref index } => {
+                                    let len = self.eval_operand(len).expect("len must be const");
+                                    let len = match len.0 {
+                                        Value::ByVal(PrimVal::Bytes(n)) => n,
+                                        _ => bug!("const len not primitive: {:?}", len),
+                                    };
+                                    let index = self
+                                        .eval_operand(index)
+                                        .expect("index must be const");
+                                    let index = match index.0 {
+                                        Value::ByVal(PrimVal::Bytes(n)) => n,
+                                        _ => bug!("const index not primitive: {:?}", index),
+                                    };
+                                    lint.span_label(
+                                        span,
+                                        format!(
+                                            "index out of bounds: \
+                                            the len is {} but the index is {}",
+                                            len,
+                                            index,
+                                        ),
+                                    )
+                                },
+                            }.emit();
+                        }
+                    }
                 }
             }
             // FIXME: do this optimization for function calls
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index d1c2c7a61d4..8856d263864 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -23,9 +23,12 @@ pub struct InstCombine;
 impl MirPass for InstCombine {
     fn run_pass<'a, 'tcx>(&self,
                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          source: MirSource,
+                          _: MirSource,
                           mir: &mut Mir<'tcx>) {
-        trace!("InstCombine starting for {:?}", source.def_id);
+        // We only run when optimizing MIR (at any level).
+        if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
+            return
+        }
 
         // First, find optimization opportunities. This is done in a pre-pass to keep the MIR
         // read-only so that we can do global analyses on the MIR in the process (e.g.
@@ -38,7 +41,6 @@ impl MirPass for InstCombine {
 
         // Then carry out those optimizations.
         MutVisitor::visit_mir(&mut InstCombineVisitor { optimizations }, mir);
-        trace!("InstCombine done for {:?}", source.def_id);
     }
 }
 
@@ -61,7 +63,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
         }
 
         if let Some(constant) = self.optimizations.arrays_lengths.remove(&location) {
-            debug!("Replacing `Len([_; N])`: {:?} with {:?}", rvalue, constant);
+            debug!("Replacing `Len([_; N])`: {:?}", rvalue);
             *rvalue = Rvalue::Use(Operand::Constant(box constant));
         }
 
@@ -77,10 +79,7 @@ struct OptimizationFinder<'b, 'a, 'tcx:'a+'b> {
 }
 
 impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
-    fn new(
-        mir: &'b Mir<'tcx>,
-        tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    ) -> OptimizationFinder<'b, 'a, 'tcx> {
+    fn new(mir: &'b Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> OptimizationFinder<'b, 'a, 'tcx> {
         OptimizationFinder {
             mir,
             tcx,