From 9ea40ad44a9b035d0835d638f928c590d7e3c618 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 2 Sep 2017 04:11:51 -0700 Subject: [PATCH] Replace SSABuilder's variables HashMaps with EntityMaps. (#150) * Replace SSABuilder's variables HashMaps with EntityMaps. Current measurements show that memory usage is approximately the same, and it's about 20% faster. * Add EntityMap::with_default and use it. * rustfmt * Use var_defs[block].expand(). --- lib/cretonne/src/entity/map.rs | 11 +++++++++++ lib/frontend/src/ssa.rs | 16 ++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/cretonne/src/entity/map.rs b/lib/cretonne/src/entity/map.rs index 5db8522382..200aa464c3 100644 --- a/lib/cretonne/src/entity/map.rs +++ b/lib/cretonne/src/entity/map.rs @@ -41,6 +41,17 @@ where } } + /// Create a new empty map with a specified default value. + /// + /// This constructor does not require V to implement Default. + pub fn with_default(default: V) -> Self { + EntityMap { + elems: Vec::new(), + default: default, + unused: PhantomData, + } + } + /// Get the element at `k` if it exists. pub fn get(&self, k: K) -> Option<&V> { self.elems.get(k.index()) diff --git a/lib/frontend/src/ssa.rs b/lib/frontend/src/ssa.rs index 2cabe2cedf..13c3dbbfc3 100644 --- a/lib/frontend/src/ssa.rs +++ b/lib/frontend/src/ssa.rs @@ -15,7 +15,6 @@ use cretonne::packed_option::ReservedValue; use std::u32; use cretonne::ir::types::{F32, F64}; use cretonne::ir::immediates::{Ieee32, Ieee64}; -use std::collections::HashMap; use std::mem; /// Structure containing the data relevant the construction of SSA for a given function. @@ -39,7 +38,7 @@ where { // Records for every variable and for every revelant block, the last definition of // the variable in the block. - variables: EntityMap>, + variables: EntityMap>>, // Records the position of the basic blocks and the list of values used but not defined in the // block. blocks: PrimaryMap>, @@ -148,7 +147,7 @@ where /// Allocate a new blank SSA builder struct. Use the API function to interact with the struct. pub fn new() -> Self { Self { - variables: EntityMap::new(), + variables: EntityMap::with_default(EntityMap::new()), blocks: PrimaryMap::new(), ebb_headers: EntityMap::new(), } @@ -207,7 +206,7 @@ where /// The SSA value is passed as an argument because it should be created with /// `ir::DataFlowGraph::append_result`. pub fn def_var(&mut self, var: Variable, val: Value, block: Block) { - self.variables[var].insert(block, val); + self.variables[var][block] = PackedOption::from(val); } /// Declares a use of a variable in a given basic block. Returns the SSA value corresponding @@ -228,8 +227,8 @@ where ) -> (Value, SideEffects) { // First we lookup for the current definition of the variable in this block if let Some(var_defs) = self.variables.get(var) { - if let Some(val) = var_defs.get(&block) { - return (*val, SideEffects::new()); + if let Some(val) = var_defs[block].expand() { + return (val, SideEffects::new()); } } @@ -478,10 +477,11 @@ where // to keep the ebb argument. for &mut (ref mut pred_block, ref mut last_inst) in &mut preds { // We already did a full `use_var` above, so we can do just the fast path. - let pred_val = *self.variables + let pred_val = self.variables .get(temp_arg_var) .unwrap() - .get(&pred_block) + .get(*pred_block) + .unwrap() .unwrap(); if let Some((middle_ebb, middle_block, middle_jump_inst)) = self.append_jump_argument(