Commit ed646119 authored by Kunshan Wang's avatar Kunshan Wang

IRBuilder: Builds func, funcver, bb (not insts yet

parent 2da94d67
......@@ -954,4 +954,4 @@ pub fn op_vector_str(vec: &Vec<OpIndex>, ops: &Vec<P<TreeNode>>) -> String {
}
}
ret
}
\ No newline at end of file
}
use super::common::*;
use ast::op::*;
pub struct MuIRBuilder {
/// ref to MuVM
mvm: *const MuVM,
......@@ -441,7 +443,9 @@ struct BundleLoader<'lb, 'lvm> {
built_sigs: IdPMap<MuFuncSig>,
built_values: IdPMap<Value>,
built_funcs: IdPMap<MuFunction>,
built_funcvers: IdPMap<MuFunctionVersion>,
struct_id_tags: Vec<(MuID, MuName)>,
built_refi64: P<MuType>,
}
fn load_bundle(b: &mut MuIRBuilder) {
......@@ -449,21 +453,50 @@ fn load_bundle(b: &mut MuIRBuilder) {
let new_map = b.id_name_map.drain().collect::<HashMap<_,_>>();
let mut built_types: IdPMap<MuType> = Default::default();
let refi64: P<MuType> = ensure_refi64(vm, &mut built_types);
let mut bl = BundleLoader {
b: b,
vm: vm,
id_name_map: new_map,
visited: Default::default(),
built_types: Default::default(),
built_types: built_types,
built_sigs: Default::default(),
built_values: Default::default(),
built_funcs: Default::default(),
built_funcvers: Default::default(),
struct_id_tags: Default::default(),
built_refi64: refi64,
};
bl.load_bundle();
}
fn ensure_refi64(vm: &VM, built_types: &mut IdPMap<MuType>) -> P<MuType> {
let id_i64 = vm.next_id();
let id_ref = vm.next_id();
let impl_i64 = P(MuType {
hdr: MuEntityHeader::unnamed(id_i64),
v: MuType_::Int(64),
});
let impl_ref = P(MuType {
hdr: MuEntityHeader::unnamed(id_ref),
v: MuType_::Ref(impl_i64.clone()),
});
trace!("Ensure i64 is defined: {} {:?}", id_i64, impl_i64);
trace!("Ensure ref is defined: {} {:?}", id_ref, impl_ref);
built_types.insert(id_i64, impl_i64);
built_types.insert(id_ref, impl_ref.clone());
impl_ref
}
impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
fn load_bundle(&mut self) {
self.ensure_names();
......@@ -547,6 +580,10 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
self.build_func(*id)
}
}
for id in self.b.bundle.funcvers.keys() {
self.build_funcver(*id)
}
}
fn build_type(&mut self, id: MuID) {
......@@ -601,6 +638,13 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
}
}
fn get_built_type(&self, id: MuID) -> P<MuType> {
match self.built_types.get(&id) {
Some(t) => t.clone(),
None => self.vm.get_type(id)
}
}
fn fill_struct(&mut self, id: MuID, tag: &MuName) {
let ty = self.b.bundle.types.get(&id).unwrap();
......@@ -718,5 +762,94 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
self.built_funcs.insert(id, P(impl_fun));
}
fn build_funcver(&mut self, id: MuID) {
let fv = self.b.bundle.funcvers.get(&id).unwrap();
trace!("Building function version {} {:?}", id, fv);
let hdr = self.make_mu_entity_header(id);
let fun = self.built_funcs.get(&fv.func).unwrap();
let impl_sig = fun.sig.clone();
let mut ctx = FunctionContext { values: Default::default() };
let blocks = fv.bbs.iter().map(|bbid| {
let block = self.build_block(*bbid, &mut ctx);
(*bbid, block)
}).collect::<HashMap<MuID, Block>>();
let entry_id = *fv.bbs.first().unwrap();
let ctn = FunctionContent {
entry: entry_id,
blocks: blocks,
};
let impl_fv = MuFunctionVersion {
hdr: hdr,
func_id: id,
sig: impl_sig,
content: Some(ctn),
context: ctx,
block_trace: None,
};
trace!("Function version built {} {:?}", id, impl_fv);
self.built_funcvers.insert(id, P(impl_fv));
}
/// Copied from ast::ir::*. That was implemented for the previous API which implies mutability.
/// When we migrate later, we can assume the AST is almost fully immutable, and can be
/// constructed in a functional recursive-descendent style.
fn new_ssa(&self, id: MuID, ty: P<MuType>, ctx: &mut FunctionContext) -> P<TreeNode> {
let hdr = self.make_mu_entity_header(id);
let val = P(Value{
hdr: hdr,
ty: ty,
v: Value_::SSAVar(id)
});
ctx.values.insert(id, SSAVarEntry::new(val.clone()));
P(TreeNode {
op: pick_op_code_for_ssa(&val.ty),
v: TreeNode_::Value(val)
})
}
fn build_block(&self, id: MuID, ctx: &mut FunctionContext) -> Block {
let bb = self.b.bundle.bbs.get(&id).unwrap();
trace!("Building basic block {} {:?}", id, bb);
let nor_ids = &bb.norParamIDs;
let nor_tys = &bb.norParamTys;
let args = nor_ids.iter().zip(nor_tys).map(|(arg_id, arg_ty_id)| {
let arg_ty = self.get_built_type(*arg_ty_id);
self.new_ssa(*arg_id, arg_ty, ctx).clone_value()
}).collect::<Vec<_>>();
let exn_arg = bb.excParamID.map(|arg_id| {
let arg_ty = self.built_refi64.clone();
self.new_ssa(arg_id, arg_ty, ctx).clone_value()
});
let hdr = self.make_mu_entity_header(id);
let ctn = BlockContent {
args: args,
exn_arg: exn_arg,
body: Default::default(), // FIXME: actually build body.
keepalives: None,
};
Block {
hdr: hdr,
content: Some(ctn),
control_flow: Default::default(),
}
}
}
......@@ -183,6 +183,37 @@ fn test_function_loading() {
((*b).new_func)(b, id4, id3);
let id5 = ((*b).gen_sym)(b, csp.get("@func.v1"));
let id6 = ((*b).gen_sym)(b, csp.get("@func.v1.entry"));
let id7 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.x"));
let id8 = ((*b).gen_sym)(b, csp.get("@func.v1.bb1"));
let id9 = ((*b).gen_sym)(b, csp.get("@func.v1.bb1.exc"));
//let id4 = ((*b).gen_sym)(b, csp.get("@func"));
let mut bbs = vec![id6, id8];
((*b).new_func_ver)(b, id5, id4, bbs.as_mut_ptr(), bbs.len());
{
let mut args = vec![id7];
let mut argtys = vec![id1];
let mut insts = vec![];
((*b).new_bb)(b, id6,
args.as_mut_ptr(), argtys.as_mut_ptr(), args.len(),
0,
insts.as_mut_ptr(), insts.len());
}
{
let mut args = vec![];
let mut argtys = vec![];
let mut insts = vec![];
((*b).new_bb)(b, id8,
args.as_mut_ptr(), argtys.as_mut_ptr(), args.len(),
id9,
insts.as_mut_ptr(), insts.len());
}
((*b).load)(b);
((*ctx).close_context)(ctx);
......
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