Commit 48b8b266 authored by qinsoon's avatar qinsoon

[wip] implementing global

parent e10103b7
......@@ -94,7 +94,15 @@ impl MuFunctionVersion {
pub fn new_constant(&mut self, v: P<Value>) -> P<TreeNode> {
P(TreeNode{
id: self.get_id(),
op: pick_op_code_for_const(&v.ty),
op: pick_op_code_for_value(&v.ty),
v: TreeNode_::Value(v)
})
}
pub fn new_global(&mut self, v: P<Value>) -> P<TreeNode> {
P(TreeNode{
id: self.get_id(),
op: pick_op_code_for_value(&v.ty),
v: TreeNode_::Value(v)
})
}
......@@ -392,6 +400,9 @@ impl fmt::Display for TreeNode {
},
Value_::Constant(ref c) => {
write!(f, "+({} {})", pv.ty, c)
},
Value_::Global(ref g) => {
write!(f, "+({} @{})", g.ty, g.tag)
}
}
},
......@@ -472,6 +483,9 @@ impl fmt::Display for Value {
},
Value_::Constant(ref c) => {
write!(f, "+({} {})", self.ty, c)
},
Value_::Global(ref g) => {
write!(f, "+({} @{})", g.ty, g.tag)
}
}
}
......@@ -480,7 +494,8 @@ impl fmt::Display for Value {
#[derive(Debug, Clone, PartialEq)]
pub enum Value_ {
SSAVar(MuID),
Constant(Constant)
Constant(Constant),
Global(P<GlobalCell>)
}
#[derive(Debug, Clone)]
......@@ -543,6 +558,12 @@ impl fmt::Display for Constant {
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct GlobalCell {
pub tag: MuTag,
pub ty: P<MuType>
}
pub fn op_vector_str(vec: &Vec<OpIndex>, ops: &Vec<P<TreeNode>>) -> String {
let mut ret = String::new();
for i in 0..vec.len() {
......
......@@ -83,7 +83,7 @@ pub fn pick_op_code_for_ssa(ty: &P<MuType>) -> OpCode {
}
}
pub fn pick_op_code_for_const(ty: &P<MuType>) -> OpCode {
pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode {
use ast::types::MuType_::*;
let a : &MuType_ = ty;
match a {
......
......@@ -556,7 +556,8 @@ impl <'a> InstructionSelection {
Value_::Constant(_) => panic!("expected ireg"),
Value_::SSAVar(_) => {
pv.clone()
}
},
Value_::Global(_) => unimplemented!()
}
}
}
......
......@@ -11,8 +11,10 @@ use std::cell::RefCell;
pub struct VMContext {
constants: RwLock<HashMap<MuTag, P<Value>>>,
types: RwLock<HashMap<MuTag, P<MuType>>>,
func_sigs: RwLock<HashMap<MuTag, P<MuFuncSig>>>,
globals: RwLock<HashMap<MuTag, P<GlobalCell>>>,
func_sigs: RwLock<HashMap<MuTag, P<MuFuncSig>>>,
func_vers: RwLock<HashMap<(MuTag, MuTag), RefCell<MuFunctionVersion>>>,
funcs: RwLock<HashMap<MuTag, RefCell<MuFunction>>>,
......@@ -24,8 +26,10 @@ impl <'a> VMContext {
VMContext {
constants: RwLock::new(HashMap::new()),
types: RwLock::new(HashMap::new()),
func_sigs: RwLock::new(HashMap::new()),
globals: RwLock::new(HashMap::new()),
func_sigs: RwLock::new(HashMap::new()),
func_vers: RwLock::new(HashMap::new()),
funcs: RwLock::new(HashMap::new()),
compiled_funcs: RwLock::new(HashMap::new())
......@@ -42,6 +46,19 @@ impl <'a> VMContext {
ret
}
pub fn declare_global(&self, global_name: MuTag, ty: P<MuType>) -> P<Value> {
let global = P(GlobalCell{tag: global_name, ty: ty.clone()});
let mut globals = self.globals.write().unwrap();
globals.insert(global_name, global.clone());
P(Value{
tag: "",
ty: P(MuType::iref(ty)),
v: Value_::Global(global.clone())
})
}
pub fn declare_type(&self, type_name: MuTag, ty: P<MuType>) -> P<MuType> {
let mut types = self.types.write().unwrap();
debug_assert!(!types.contains_key(type_name));
......
mod test_pre_instsel;
mod test_instsel;
mod test_regalloc;
mod test_global;
\ No newline at end of file
extern crate mu;
extern crate log;
extern crate simple_logger;
use test_ir::test_ir::global_access;
use self::mu::compiler::*;
use std::sync::Arc;
#[test]
fn test_global_access() {
simple_logger::init_with_level(log::LogLevel::Trace).ok();
let vm_context = Arc::new(global_access());
let compiler = Compiler::new(CompilerPolicy::new(vec![
Box::new(passes::DefUse::new()),
Box::new(passes::TreeGen::new()),
Box::new(passes::ControlFlowAnalysis::new()),
Box::new(passes::TraceGen::new()),
Box::new(backend::inst_sel::InstructionSelection::new()),
Box::new(backend::reg_alloc::RegisterAllocation::new()),
Box::new(backend::peephole_opt::PeepholeOptimization::new()),
Box::new(backend::code_emission::CodeEmission::new())
]), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap();
let func = funcs.get("global_access").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.fn_name, func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut func_ver);
}
......@@ -22,6 +22,12 @@ fn test_sum() {
let vm = sum();
}
#[test]
#[allow(unused_variables)]
fn test_global_access() {
let vm = global_access();
}
pub fn sum() -> VMContext {
let vm = VMContext::new();
......@@ -316,3 +322,86 @@ pub fn factorial() -> VMContext {
vm
}
#[allow(unused_variables)]
pub fn global_access() -> VMContext {
let vm = VMContext::new();
// .typedef @int64 = int<64>
// .typedef @iref_int64 = iref<int<64>>
let type_def_int64 = vm.declare_type("int64", P(MuType::int(64)));
let type_def_iref_int64 = vm.declare_type("iref_int64", P(MuType::iref(type_def_int64.clone())));
// .const @int_64_0 <@int_64> = 0
// .const @int_64_1 <@int_64> = 1
let const_def_int64_0 = vm.declare_const("int64_0", type_def_int64.clone(), Constant::Int(0));
let const_def_int64_1 = vm.declare_const("int64_1", type_def_int64.clone(), Constant::Int(1));
// .global @a <@int_64>
let global_a = vm.declare_global("a", type_def_int64.clone());
// .funcsig @global_access_sig = () -> ()
let func_sig = vm.declare_func_sig("global_access_sig", vec![], vec![]);
// .funcdecl @global_access <@global_access_sig>
let func = MuFunction::new("global_access", func_sig.clone());
vm.declare_func(func);
// .funcdef @global_access VERSION @v1 <@global_access_sig>
let mut func_ver = MuFunctionVersion::new("global_access", "v1", func_sig.clone());
// %blk_0():
let mut blk_0 = Block::new("blk_0");
// %x = LOAD <@int_64> @a
let blk_0_x = func_ver.new_ssa("blk_0_x", type_def_iref_int64.clone()).clone_value();
let blk_0_a = func_ver.new_global(global_a.clone());
let blk_0_inst0 = func_ver.new_inst(Instruction{
value: Some(vec![blk_0_x]),
ops: RefCell::new(vec![blk_0_a.clone()]),
v: Instruction_::Load{
is_ptr: false,
order: MemoryOrder::SeqCst,
mem_loc: 0
}
});
// STORE <@int_64> @a @int_64_1
let blk_0_const_int64_1 = func_ver.new_constant(const_def_int64_1.clone());
let blk_0_inst1 = func_ver.new_inst(Instruction{
value: None,
ops: RefCell::new(vec![blk_0_a.clone(), blk_0_const_int64_1.clone()]),
v: Instruction_::Store{
is_ptr: false,
order: MemoryOrder::SeqCst,
mem_loc: 0,
value: 1
}
});
let blk_0_term = func_ver.new_inst(Instruction{
value: None,
ops: RefCell::new(vec![]),
v: Instruction_::Return(vec![])
});
let blk_0_content = BlockContent {
args: vec![],
body: vec![blk_0_inst0, blk_0_inst1, blk_0_term],
keepalives: None
};
blk_0.content = Some(blk_0_content);
func_ver.define(FunctionContent{
entry: "blk_0",
blocks: {
let mut ret = HashMap::new();
ret.insert("blk_0", blk_0);
ret
}
});
vm.define_func_version(func_ver);
vm
}
\ No newline at end of file
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