Commit 36d38ac7 authored by qinsoon's avatar qinsoon

replacing most uses of HashMap with LinkedHashMap. This will reduce (if not…

replacing most uses of HashMap with LinkedHashMap. This will reduce (if not eliminate) undeterminism in the compilation.
Copied LinkedHashMap implementation to local so that I can implement encode/decode and other necessary methods
parent f092e7f3
Pipeline #219 failed with stage
in 23 minutes and 53 seconds
......@@ -4,6 +4,7 @@ use inst::*;
use op::*;
use utils::vec_utils;
use utils::LinkedHashMap;
use std::collections::HashMap;
use std::fmt;
......@@ -293,7 +294,7 @@ impl MuFunctionVersion {
#[derive(RustcEncodable, RustcDecodable)]
pub struct FunctionContent {
pub entry: MuID,
pub blocks: HashMap<MuID, Block>
pub blocks: LinkedHashMap<MuID, Block>
}
impl fmt::Debug for FunctionContent {
......@@ -313,7 +314,7 @@ impl fmt::Debug for FunctionContent {
impl Clone for FunctionContent {
fn clone(&self) -> Self {
let mut new_blocks = HashMap::new();
let mut new_blocks = LinkedHashMap::new();
for (id, block) in self.blocks.iter() {
new_blocks.insert(*id, block.clone());
......
......@@ -18,6 +18,7 @@ use ast::ir::*;
use ast::types::*;
use compiler::backend::RegGroup;
use utils::LinkedHashMap;
use std::collections::HashMap;
macro_rules! GPR_ALIAS {
......@@ -96,8 +97,8 @@ GPR_ALIAS!(R15_ALIAS: (64,R15) -> R15D,R15W,R15B);
GPR_ALIAS!(RIP_ALIAS: (68,RIP));
lazy_static! {
pub static ref GPR_ALIAS_TABLE : HashMap<MuID, Vec<P<Value>>> = {
let mut ret = HashMap::new();
pub static ref GPR_ALIAS_TABLE : LinkedHashMap<MuID, Vec<P<Value>>> = {
let mut ret = LinkedHashMap::new();
ret.insert(RAX.id(), RAX_ALIAS.to_vec());
ret.insert(RCX.id(), RCX_ALIAS.to_vec());
......@@ -346,8 +347,8 @@ lazy_static!{
}
lazy_static! {
pub static ref ALL_MACHINE_REGs : HashMap<MuID, P<Value>> = {
let mut map = HashMap::new();
pub static ref ALL_MACHINE_REGs : LinkedHashMap<MuID, P<Value>> = {
let mut map = LinkedHashMap::new();
for vec in GPR_ALIAS_TABLE.values() {
for reg in vec {
......@@ -432,7 +433,7 @@ pub fn number_of_all_regs() -> usize {
ALL_MACHINE_REGs.len()
}
pub fn all_regs() -> &'static HashMap<MuID, P<Value>> {
pub fn all_regs() -> &'static LinkedHashMap<MuID, P<Value>> {
&ALL_MACHINE_REGs
}
......
......@@ -7,9 +7,10 @@ use vm::VM;
use utils::vec_utils;
use utils::LinkedHashSet;
use utils::LinkedHashMap;
use std::collections::HashMap;
use std::cell::RefCell;
use std::collections::HashMap;
use compiler::backend::reg_alloc::graph_coloring::liveness::Move;
use compiler::backend::reg_alloc::graph_coloring::petgraph::graph::NodeIndex;
......@@ -24,22 +25,22 @@ pub struct GraphColoring<'a> {
pub ig: InterferenceGraph,
precolored: LinkedHashSet<NodeIndex>,
colors: HashMap<backend::RegGroup, LinkedHashSet<MuID>>,
colors: LinkedHashMap<backend::RegGroup, LinkedHashSet<MuID>>,
pub colored_nodes: Vec<NodeIndex>,
initial: Vec<NodeIndex>,
degree: HashMap<NodeIndex, usize>,
degree: LinkedHashMap<NodeIndex, usize>,
worklist_moves: Vec<Move>,
movelist: HashMap<NodeIndex, RefCell<Vec<Move>>>,
movelist: LinkedHashMap<NodeIndex, RefCell<Vec<Move>>>,
active_moves: LinkedHashSet<Move>,
coalesced_nodes: LinkedHashSet<NodeIndex>,
coalesced_moves: LinkedHashSet<Move>,
constrained_moves: LinkedHashSet<Move>,
alias: HashMap<NodeIndex, NodeIndex>,
alias: LinkedHashMap<NodeIndex, NodeIndex>,
worklist_spill: Vec<NodeIndex>,
spillable: HashMap<MuID, bool>,
spillable: LinkedHashMap<MuID, bool>,
spilled_nodes: Vec<NodeIndex>,
worklist_freeze: LinkedHashSet<NodeIndex>,
......@@ -65,7 +66,7 @@ impl <'a> GraphColoring<'a> {
precolored: LinkedHashSet::new(),
colors: {
let mut map = HashMap::new();
let mut map = LinkedHashMap::new();
map.insert(backend::RegGroup::GPR, LinkedHashSet::new());
map.insert(backend::RegGroup::FPR, LinkedHashSet::new());
map
......@@ -73,18 +74,18 @@ impl <'a> GraphColoring<'a> {
colored_nodes: Vec::new(),
initial: Vec::new(),
degree: HashMap::new(),
degree: LinkedHashMap::new(),
worklist_moves: Vec::new(),
movelist: HashMap::new(),
movelist: LinkedHashMap::new(),
active_moves: LinkedHashSet::new(),
coalesced_nodes: LinkedHashSet::new(),
coalesced_moves: LinkedHashSet::new(),
constrained_moves: LinkedHashSet::new(),
alias: HashMap::new(),
alias: LinkedHashMap::new(),
worklist_spill: Vec::new(),
spillable: HashMap::new(),
spillable: LinkedHashMap::new(),
spilled_nodes: Vec::new(),
worklist_freeze: LinkedHashSet::new(),
......@@ -252,19 +253,19 @@ impl <'a> GraphColoring<'a> {
// avoid using &mut self as argument
// in build(), we will need to mutate on self.movelist while
// holding an immmutable reference of self(self.ig)
fn movelist_mut(list: &mut HashMap<NodeIndex, RefCell<Vec<Move>>>, node: NodeIndex) -> &RefCell<Vec<Move>> {
fn movelist_mut(list: &mut LinkedHashMap<NodeIndex, RefCell<Vec<Move>>>, node: NodeIndex) -> &RefCell<Vec<Move>> {
GraphColoring::movelist_check(list, node);
unsafe {GraphColoring::movelist_nocheck(list, node)}
}
fn movelist_check(list: &mut HashMap<NodeIndex, RefCell<Vec<Move>>>, node: NodeIndex) {
fn movelist_check(list: &mut LinkedHashMap<NodeIndex, RefCell<Vec<Move>>>, node: NodeIndex) {
if !list.contains_key(&node) {
list.insert(node, RefCell::new(Vec::new()));
}
}
// allows getting the Vec<Move> without a mutable reference of the hashmap
unsafe fn movelist_nocheck(list: &HashMap<NodeIndex, RefCell<Vec<Move>>>, node: NodeIndex) -> &RefCell<Vec<Move>> {
unsafe fn movelist_nocheck(list: &LinkedHashMap<NodeIndex, RefCell<Vec<Move>>>, node: NodeIndex) -> &RefCell<Vec<Move>> {
list.get(&node).unwrap()
}
......
......@@ -3,8 +3,7 @@ use ast::inst::Instruction_::*;
use utils::vec_utils::as_str as vector_as_str;
use vm::VM;
use compiler::CompilerPass;
use std::collections::HashMap;
use utils::LinkedHashMap;
use std::any::Any;
pub struct ControlFlowAnalysis {
......@@ -95,10 +94,10 @@ fn dfs(cur: MuID, stack: &mut Vec<MuID>, visited: &mut Vec<MuID>, func: &mut MuF
const BRANCH_DEFAULT_PROB : f32 = 0.1;
let switch_prob = (1.0f32 - BRANCH_DEFAULT_PROB) / (branches.len() as f32);
let map : HashMap<MuID, BlockEdge> = {
let mut ret = HashMap::new();
let map : LinkedHashMap<MuID, BlockEdge> = {
let mut ret = LinkedHashMap::new();
let check_add_edge = |map: &mut HashMap<MuID, BlockEdge>, target: MuID, prob: f32| {
let check_add_edge = |map: &mut LinkedHashMap<MuID, BlockEdge>, target: MuID, prob: f32| {
if map.contains_key(&target) {
let mut edge : &mut BlockEdge = map.get_mut(&target).unwrap();
edge.probability += prob;
......
......@@ -108,11 +108,13 @@ impl Inlining {
let mut new_blocks : Vec<Block> = vec![];
for (_, block) in f_content.blocks.drain() {
for (_, block) in f_content.blocks.iter() {
// clone curent block, and clear its instructions
let mut cur_block = block.clone();
cur_block.content.as_mut().unwrap().body.clear();
let block = block.clone();
// iterate through instructions
for inst in block.content.unwrap().body {
trace!("check inst: {}", inst);
......
......@@ -9,5 +9,5 @@ crate-type = ["rlib"]
[dependencies]
memmap = "0.4.0"
memsec = "0.1.9"
linked-hash-map = "0.0.10"
byteorder = "0.5.3"
\ No newline at end of file
byteorder = "0.5.3"
rustc-serialize = "*"
\ No newline at end of file
extern crate byteorder;
extern crate rustc_serialize;
pub type ByteSize = usize;
pub type Word = usize;
......@@ -11,9 +12,28 @@ pub const WORD_SIZE : ByteSize = 1 << LOG_POINTER_SIZE;
pub mod mem;
mod linked_hashmap;
mod linked_hashset;
pub use linked_hashmap::LinkedHashMap;
pub use linked_hashset::LinkedHashSet;
pub use linked_hashset::LinkedHashMap;
#[macro_export]
macro_rules! linked_hashmap {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(linked_hashmap!(@single $rest)),*]));
($($key:expr => $value:expr,)+) => { linked_hashmap!($($key => $value),+) };
($($key:expr => $value:expr),*) => {
{
let _cap = linked_hashmap!(@count $($key),*);
let mut _map = LinkedHashMap::with_capacity(_cap);
$(
_map.insert($key, $value);
)*
_map
}
};
}
mod address;
pub use address::Address;
......
This diff is collapsed.
extern crate linked_hash_map;
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash};
use std::borrow::Borrow;
use self::linked_hash_map::Keys;
pub use self::linked_hash_map::LinkedHashMap;
use linked_hashmap::LinkedHashMap;
use linked_hashmap::Keys;
pub struct LinkedHashSet<K, S = RandomState>(LinkedHashMap<K, (), S>);
......
use super::common::*;
use ast::op::*;
use ast::inst::*;
use utils::LinkedHashMap;
use std;
pub struct MuIRBuilder {
......@@ -1135,7 +1136,7 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
let blocks = fv.bbs.iter().map(|bbid| {
let block = self.build_block(&mut fcb, *bbid);
(*bbid, block)
}).collect::<HashMap<MuID, Block>>();
}).collect::<LinkedHashMap<MuID, Block>>();
let entry_id = *fv.bbs.first().unwrap();
let ctn = FunctionContent {
......
......@@ -79,8 +79,10 @@ macro_rules! define_func_ver {
(($vm: expr) $fv: ident (entry: $entry: ident){$($blk: ident), *}) => {
$fv.define(FunctionContent{
entry: $entry.id(),
blocks: hashmap!{
$($blk.id() => $blk),*
blocks: {
let mut ret = LinkedHashMap::new();
$ (ret.insert($blk.id(), $blk); )*
ret
}
});
......
#[macro_use]
extern crate mu;
#[macro_use]
extern crate log;
......
......@@ -9,10 +9,10 @@ use self::mu::vm::*;
use self::mu::compiler::*;
use self::mu::runtime::thread::MuThread;
use self::mu::utils::Address;
use self::mu::utils::LinkedHashMap;
use std::sync::Arc;
use std::sync::RwLock;
use std::collections::HashMap;
use self::mu::testutil::aot;
#[test]
......@@ -179,7 +179,7 @@ pub fn alloc_new() -> VM {
func_ver.define(FunctionContent{
entry: blk_0.id(),
blocks: {
let mut ret = HashMap::new();
let mut ret = LinkedHashMap::new();
ret.insert(blk_0.id(), blk_0);
ret
}
......
......@@ -8,6 +8,7 @@ use self::mu::ast::inst::*;
use self::mu::ast::op::*;
use self::mu::vm::*;
use self::mu::testutil;
use mu::utils::LinkedHashMap;
use std::sync::RwLock;
......@@ -81,8 +82,10 @@ fn udiv() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map
}
});
......@@ -165,8 +168,10 @@ fn sdiv() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map
}
});
......@@ -252,8 +257,10 @@ fn shl() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map
}
});
......@@ -335,8 +342,10 @@ fn lshr() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map
}
});
......
......@@ -8,6 +8,7 @@ use mu::compiler::*;
use std::sync::RwLock;
use std::sync::Arc;
use mu::testutil::aot;
use mu::utils::LinkedHashMap;
#[test]
fn test_ccall_exit() {
......@@ -131,8 +132,10 @@ fn ccall_exit() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map
}
});
......
......@@ -6,6 +6,7 @@ use mu::ast::inst::*;
use mu::ast::op::*;
use mu::vm::*;
use mu::testutil;
use mu::utils::LinkedHashMap;
use std::sync::RwLock;
......@@ -191,12 +192,14 @@ fn switch() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry,
blk_default_id => blk_default,
blk_ret0_id => blk_ret0,
blk_ret1_id => blk_ret1,
blk_ret2_id => blk_ret2
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map.insert(blk_default_id, blk_default);
map.insert(blk_ret0_id, blk_ret0);
map.insert(blk_ret1_id, blk_ret1);
map.insert(blk_ret2_id, blk_ret2);
map
}
});
......
......@@ -7,12 +7,12 @@ use self::mu::ast::ir::*;
use self::mu::ast::inst::*;
use self::mu::vm::*;
use self::mu::compiler::*;
use self::mu::utils::LinkedHashMap;
use self::mu::testutil::aot;
use std::sync::Arc;
use std::sync::RwLock;
use std::collections::HashMap;
#[test]
fn test_exception_simple_throw_catch() {
......@@ -172,7 +172,7 @@ fn create_catch_exception_func (vm: &VM) {
func_ver.define(FunctionContent{
entry: blk_0.id(),
blocks: {
let mut ret = HashMap::new();
let mut ret = LinkedHashMap::new();
ret.insert(blk_0.id(), blk_0);
ret.insert(blk_normal_cont.id(), blk_normal_cont);
ret.insert(blk_exn_cont.id(), blk_exn_cont);
......@@ -257,7 +257,7 @@ fn create_throw_exception_func (vm: &VM) {
func_ver.define(FunctionContent {
entry: blk_0.id(),
blocks: {
let mut ret = HashMap::new();
let mut ret = LinkedHashMap::new();
ret.insert(blk_0.id(), blk_0);
ret
}
......
......@@ -9,6 +9,7 @@ use self::mu::ast::op::*;
use self::mu::vm::*;
use self::mu::compiler::*;
use self::mu::testutil;
use mu::utils::LinkedHashMap;
use std::sync::RwLock;
use std::sync::Arc;
......@@ -104,8 +105,10 @@ fn fp_add() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut ret = LinkedHashMap::new();
ret.insert(blk_entry.id(), blk_entry);
ret
}
});
......
......@@ -5,12 +5,10 @@ use mu::ast::ir::*;
use mu::ast::inst::*;
use mu::ast::op::*;
use mu::vm::*;
use mu::compiler::*;
use mu::testutil;
use mu::utils::LinkedHashMap;
use std::sync::Arc;
use std::sync::RwLock;
use mu::testutil::aot;
#[test]
fn test_inline_add() {
......
......@@ -6,6 +6,7 @@ use self::mu::ast::ir::*;
use self::mu::ast::inst::*;
use self::mu::ast::op::*;
use self::mu::vm::*;
use self::mu::utils::LinkedHashMap;
use std::sync::RwLock;
use mu::testutil;
......@@ -84,8 +85,10 @@ fn add_u8() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map
}
});
......@@ -221,8 +224,10 @@ fn sext() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map
}
});
......@@ -305,8 +310,10 @@ fn add_9f() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map
}
});
......
......@@ -4,6 +4,7 @@ use mu::ast::inst::*;
use mu::ast::op::*;
use mu::vm::*;
use mu::compiler::*;
use mu::utils::LinkedHashMap;
use std::sync::Arc;
use std::sync::RwLock;
......@@ -372,9 +373,11 @@ pub fn struct_insts() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry,
blk_check_id => blk_check
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map.insert(blk_check_id, blk_check);
map
}
});
......@@ -650,9 +653,11 @@ pub fn hybrid_fix_part_insts() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry,
blk_check_id => blk_check
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map.insert(blk_check_id, blk_check);
map
}
});
......@@ -1092,12 +1097,14 @@ pub fn hybrid_var_part_insts() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: hashmap!{
blk_entry.id() => blk_entry,
blk_check.id() => blk_check,
blk_head.id() => blk_head,
blk_body.id() => blk_body,
blk_exit.id() => blk_exit
blocks: {
let mut map = LinkedHashMap::new();
map.insert(blk_entry.id(), blk_entry);
map.insert(blk_check.id(), blk_check);
map.insert(blk_head.id(), blk_head);
map.insert(blk_body.id(), blk_body);
map.insert(blk_exit.id(), blk_exit);
map
}
});
......
......@@ -2,6 +2,7 @@ extern crate mu;
extern crate libloading;
use mu::testutil::aot;
use mu::utils::LinkedHashMap;
use test_ir::test_ir::factorial;
use self::mu::compiler::*;
use self::mu::utils::vec_utils;
......@@ -13,7 +14,6 @@ use self::mu::vm::VM;
use std::sync::Arc;
use std::sync::RwLock;
use std::collections::HashMap;
fn get_number_of_moves(fv_id: MuID, vm: &VM) -> usize {
let cfs = vm.compiled_funcs().read().unwrap();
......@@ -280,7 +280,7 @@ fn create_spill1() -> VM {
func_ver.define(FunctionContent {
entry: blk_entry.id(),
blocks: {
let mut blocks = HashMap::new();
let mut blocks = LinkedHashMap::new();
blocks.insert(blk_entry.id(), blk_entry);
blocks
}
......@@ -570,7 +570,7 @@ fn create_simple_spill() -> VM {
func_ver.define(FunctionContent {
entry: blk_entry.id(),
blocks: {
let mut blocks = HashMap::new();
let mut blocks = LinkedHashMap::new();
blocks.insert(blk_entry.id(), blk_entry);
blocks.insert(blk_start.id(), blk_start);
blocks.insert(blk_ret.id(), blk_ret);
......
......@@ -8,12 +8,11 @@ use self::mu::ast::inst::*;
use self::mu::ast::op::*;
use self::mu::vm::*;
use self::mu::compiler::*;
use self::mu::utils::LinkedHashMap;
use self::mu::testutil::aot;
use std::sync::Arc;
use std::sync::RwLock;
use std::collections::HashMap;
#[test]
fn test_thread_create() {
......@@ -71,7 +70,7 @@ fn primordial_main() -> VM {
func_ver.define(FunctionContent {
entry: blk_entry.id(),
blocks: {
let mut blocks = HashMap::new();
let mut blocks = LinkedHashMap::new();
blocks.insert(blk_entry.id(), blk_entry);
blocks
}
......
......@@ -5,9 +5,9 @@ use self::mu::ast::ir::*;
use self::mu::ast::inst::*;
use self::mu::ast::op::*;
use self::mu::vm::*;
use self::mu::utils::LinkedHashMap;
use std::sync::RwLock;
use std::collections::HashMap;
#[test]
#[allow(unused_variables)]
......@@ -167,7 +167,7 @@ pub fn sum() -> VM {
func_ver.define(FunctionContent{
entry: blk_entry.id(),
blocks: {
let mut blocks = HashMap::new();
let mut blocks = LinkedHashMap::new();
blocks.insert(blk_entry.id(), blk_entry);
blocks.insert(blk_head.id(), blk_head);
blocks.insert(blk_ret.id(), blk_ret);
......@@ -365,7 +365,7 @@ pub fn factorial() -> VM {
func_ver.define(FunctionContent{
entry: blk_0.id(),
blocks: {
let mut blocks = HashMap::new();
let mut blocks = LinkedHashMap::new();
blocks.insert(blk_0.id(), blk_0);
blocks.insert(blk_1.id(), blk_1);
blocks.insert(blk_2.id(), blk_2);
......@@ -470,7 +470,7 @@ pub fn global_access() -> VM {
func_ver.define(FunctionContent{
entry: blk_0.id(),
blocks: {
let mut ret = HashMap::new();
let mut ret = LinkedHashMap::new();
ret.insert(blk_0.id(), blk_0);
ret
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment