WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.3% of users enabled 2FA.

Commit 832c8b0e authored by qinsoon's avatar qinsoon
Browse files

[wip] output machine code as dot graph as well

parent a82c8931
......@@ -650,8 +650,9 @@ impl MachineCode for ASMCode {
}
fn set_inst_nop(&mut self, index: usize) {
self.code.remove(index);
self.code.insert(index, ASMInst::nop());
self.code[index].code.clear();
// self.code.remove(index);
// self.code.insert(index, ASMInst::nop());
}
fn remove_unnecessary_callee_saved(&mut self, used_callee_saved: Vec<MuID>) -> Vec<MuID> {
......@@ -738,6 +739,20 @@ impl MachineCode for ASMCode {
ret
}
fn emit_inst(&self, index: usize) -> Vec<u8> {
let mut ret = vec![];
let ref inst = self.code[index];
if !inst.is_symbol {
ret.append(&mut "\t".to_string().into_bytes());
}
ret.append(&mut inst.code.clone().into_bytes());
ret
}
fn trace_mc(&self) {
trace!("");
......@@ -797,6 +812,16 @@ impl MachineCode for ASMCode {
}
}
fn get_block_for_inst(&self, index: usize) -> Option<MuName> {
for (name, block) in self.blocks.iter() {
if index >= block.start_inst && index < block.end_inst {
return Some(name.clone());
}
}
None
}
fn get_next_inst(&self, index: usize) -> Option<usize> {
ASMCode::find_next_inst(index, &self.code)
}
......
......@@ -9,8 +9,10 @@ use std::any::Any;
use std::path;
use std::io::prelude::*;
use std::fs::File;
use std::collections::HashMap;
const EMIT_MUIR : bool = true;
const EMIT_MC_DOT : bool = true;
pub fn create_emit_directory(vm: &VM) {
use std::fs;
......@@ -20,6 +22,17 @@ pub fn create_emit_directory(vm: &VM) {
}
}
fn create_emit_file(name: String, vm: &VM) -> File {
let mut file_path = path::PathBuf::new();
file_path.push(&vm.vm_options.flag_aot_emit_dir);
file_path.push(name);
match File::create(file_path.as_path()) {
Err(why) => panic!("couldn't create emit file {}: {}", file_path.to_str().unwrap(), why),
Ok(file) => file
}
}
pub struct CodeEmission {
name: &'static str
}
......@@ -128,12 +141,12 @@ fn emit_muir_dot_inner(file: &mut File,
file.write_fmt(format_args!("digraph {} {{\n", f_name)).unwrap();
// node shape: rect
file.write("node [shape=rect];".as_bytes()).unwrap();
file.write("node [shape=rect];\n".as_bytes()).unwrap();
// every graph node (basic block)
for (id, block) in f_content.blocks.iter() {
let block_name = block.name().unwrap();
// BBid: [label = "name
// BBid [label = "name
file.write_fmt(format_args!("BB{} [label = \"{} ", *id, &block_name)).unwrap();
let block_content = block.content.as_ref().unwrap();
......@@ -257,6 +270,77 @@ fn emit_muir_dot_inner(file: &mut File,
file.write("}".as_bytes()).unwrap();
}
fn emit_mc_dot(func: &MuFunctionVersion, vm: &VM) {
let func_name = match func.name() {
Some(name) => name,
None => {
// use func name
vm.name_of(func.func_id)
}
};
// create emit directory/file
create_emit_directory(vm);
let mut file = create_emit_file(func_name.clone() + "_mc.dot", &vm);
// diagraph func {
file.write_fmt(format_args!("digraph {} {{\n", func_name)).unwrap();
// node shape: rect
file.write("node [shape=rect];\n".as_bytes()).unwrap();
let compiled_funcs = vm.compiled_funcs().read().unwrap();
let cf = compiled_funcs.get(&func.id()).unwrap().read().unwrap();
let mc = cf.mc();
let blocks = mc.get_all_blocks();
type DotID = usize;
let name_id_map : HashMap<MuName, DotID> = {
let mut ret = HashMap::new();
let mut index = 0;
for block_name in blocks.iter() {
ret.insert(block_name.clone(), index);
index += 1;
}
ret
};
let id = |x: MuName| name_id_map.get(&x).unwrap();
for block_name in blocks.iter() {
// BB [label = "
file.write_fmt(format_args!("{} [label = \"{}:\\n\\n", id(block_name.clone()), block_name)).unwrap();
for inst in mc.get_block_range(&block_name).unwrap() {
file.write(&mc.emit_inst(inst)).unwrap();
file.write("\\l".as_bytes()).unwrap();
}
// "];
file.write("\"];\n".as_bytes()).unwrap();
}
for block_name in blocks.iter() {
let end_inst = mc.get_block_range(block_name).unwrap().end;
for succ in mc.get_succs(mc.get_last_inst(end_inst).unwrap()).into_iter() {
match mc.get_block_for_inst(*succ) {
Some(target) => {
let source_id = id(block_name.clone());
let target_id = id(target.clone());
file.write_fmt(format_args!("{} -> {};\n", source_id, target_id)).unwrap();
}
None => {
panic!("cannot find block for inst {}", succ);
}
}
}
}
file.write("}".as_bytes()).unwrap();
}
impl CompilerPass for CodeEmission {
fn name(&self) -> &'static str {
self.name
......@@ -272,5 +356,9 @@ impl CompilerPass for CodeEmission {
if EMIT_MUIR {
emit_muir_dot(func, vm);
}
if EMIT_MC_DOT {
emit_mc_dot(func, vm);
}
}
}
......@@ -146,6 +146,7 @@ pub trait MachineCode {
fn trace_inst(&self, index: usize);
fn emit(&self) -> Vec<u8>;
fn emit_inst(&self, index: usize) -> Vec<u8>;
fn number_of_insts(&self) -> usize;
......@@ -175,6 +176,7 @@ pub trait MachineCode {
fn get_entry_block(&self) -> MuName;
// returns [start_inst, end_inst) // end_inst not included
fn get_block_range(&self, block: &str) -> Option<ops::Range<usize>>;
fn get_block_for_inst(&self, index: usize) -> Option<MuName>;
// functions for rewrite
......
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