diff options
| author | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2018-01-29 08:50:47 +0100 |
|---|---|---|
| committer | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2018-03-08 08:34:13 +0100 |
| commit | 00c95b29bce5a6aa0acb10f78418760d5249394a (patch) | |
| tree | 52016d6871f6aa5871da999441032c5d8d1ad561 | |
| parent | 54615ec9894f4f101bb15d70b6dc9b0c61f1249c (diff) | |
| download | rust-00c95b29bce5a6aa0acb10f78418760d5249394a.tar.gz rust-00c95b29bce5a6aa0acb10f78418760d5249394a.zip | |
Revert all changes to the instcombine pass
| -rw-r--r-- | src/librustc/ty/error.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/transform/const_prop.rs | 83 | ||||
| -rw-r--r-- | src/librustc_mir/transform/instcombine.rs | 15 |
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, |
