about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <public.oliver.schneider@kit.edu>2018-01-29 15:12:45 +0100
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2018-03-08 08:34:14 +0100
commit929a4cece569b7436bffd0ec76b672da7af42d1c (patch)
tree7693b4599981c98ae219f037cf474562a78dac3a
parent8c8a4335323c3c5fe917aff4ba4acb22804abf3e (diff)
downloadrust-929a4cece569b7436bffd0ec76b672da7af42d1c.tar.gz
rust-929a4cece569b7436bffd0ec76b672da7af42d1c.zip
Use IndexVec instead of FxHashMap
-rw-r--r--src/librustc_mir/transform/const_prop.rs43
1 files changed, 19 insertions, 24 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 35fce184beb..e1a1c473730 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -15,16 +15,17 @@
 
 use rustc::mir::{Constant, Literal, Location, Place, Mir, Operand, Rvalue, Local};
 use rustc::mir::{NullOp, StatementKind, Statement, BasicBlock, LocalKind};
-use rustc::mir::TerminatorKind;
+use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo};
 use rustc::mir::visit::Visitor;
+use rustc::ty::layout::LayoutOf;
 use rustc::middle::const_val::ConstVal;
 use rustc::ty::{TyCtxt, self, Instance};
 use rustc::mir::interpret::{Value, PrimVal, GlobalId};
 use interpret::{eval_body_with_mir, eval_body, mk_borrowck_eval_cx, unary_op, ValTy};
-use rustc::util::nodemap::FxHashMap;
 use transform::{MirPass, MirSource};
 use syntax::codemap::Span;
 use rustc::ty::subst::Substs;
+use rustc_data_structures::indexed_vec::IndexVec;
 
 pub struct ConstProp;
 
@@ -35,9 +36,10 @@ impl MirPass for ConstProp {
                           mir: &mut Mir<'tcx>) {
         trace!("ConstProp starting for {:?}", source.def_id);
 
-        // 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.
-        // `Place::ty()`).
+        // FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
+        // constants, instead of just checking for const-folding succeeding.
+        // That would require an uniform one-def no-mutation analysis
+        // and RPO (or recursing when needing the value of a local).
         let mut optimization_finder = OptimizationFinder::new(mir, tcx, source);
         optimization_finder.visit_mir(mir);
 
@@ -52,7 +54,7 @@ struct OptimizationFinder<'b, 'a, 'tcx:'a+'b> {
     mir: &'b Mir<'tcx>,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     source: MirSource,
-    places: FxHashMap<Local, Const<'tcx>>,
+    places: IndexVec<Local, Option<Const<'tcx>>>,
 }
 
 impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
@@ -65,7 +67,7 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
             mir,
             tcx,
             source,
-            places: FxHashMap::default(),
+            places: IndexVec::from_elem(None, &mir.local_decls),
         }
     }
 
@@ -117,7 +119,7 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
         match *op {
             Operand::Constant(ref c) => self.eval_constant(c),
             Operand::Move(ref place) | Operand::Copy(ref place) => match *place {
-                Place::Local(loc) => self.places.get(&loc).cloned(),
+                Place::Local(loc) => self.places[loc].clone(),
                 // FIXME(oli-obk): field and index projections
                 Place::Projection(_) => None,
                 _ => None,
@@ -129,8 +131,9 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
         &mut self,
         rvalue: &Rvalue<'tcx>,
         place_ty: ty::Ty<'tcx>,
-        span: Span,
+        source_info: SourceInfo,
     ) -> Option<Const<'tcx>> {
+        let span = source_info.span;
         match *rvalue {
             // No need to overwrite an already evaluated constant
             Rvalue::Use(Operand::Constant(box Constant {
@@ -213,20 +216,12 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
                 let ecx = mk_borrowck_eval_cx(self.tcx, instance, self.mir, span).unwrap();
 
                 let r = ecx.value_to_primval(ValTy { value: right.0, ty: right.1 }).ok()?;
-                let param_env = ParamEnv::empty(traits::Reveal::All);
-                let bits = (self.tcx, param_env).layout_of(left.ty).unwrap().size.bits();
-                if r >= bits as u128 {
-                    let data = &self.mir[location.block];
-                    let stmt_idx = location.statement_index;
-                    let source_info = if stmt_idx < data.statements.len() {
-                        data.statements[stmt_idx].source_info
-                    } else {
-                        data.terminator().source_info
-                    };
-                    let span = source_info.span;
+                let param_env = self.tcx.param_env(self.source.def_id);
+                let bits = (self.tcx, param_env).layout_of(left.1).unwrap().size.bits();
+                if r.to_bytes().ok()? >= bits as u128 {
                     let scope_info = match self.mir.visibility_scope_info {
                         ClearCrossCrate::Set(ref data) => data,
-                        ClearCrossCrate::Clear => return,
+                        ClearCrossCrate::Clear => return None,
                     };
                     let node_id = scope_info[source_info.scope].lint_root;
                     self.tcx.lint_node(
@@ -369,13 +364,13 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
             let place_ty = place
                 .ty(&self.mir.local_decls, self.tcx)
                 .to_ty(self.tcx);
-            let span = statement.source_info.span;
-            if let Some(value) = self.const_prop(rval, place_ty, span) {
+            if let Some(value) = self.const_prop(rval, place_ty, statement.source_info) {
                 if let Place::Local(local) = *place {
                     if self.mir.local_kind(local) == LocalKind::Temp
                         && CanConstProp::check(local, self.mir) {
                         trace!("storing {:?} to {:?}", value, local);
-                        assert!(self.places.insert(local, value).is_none());
+                        assert!(self.places[local].is_none());
+                        self.places[local] = Some(value);
                     }
                 }
             }