Commit e9c4386b authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano

Made IR output compatiable with MUC (hopefully)

parent 9b82225d
Pipeline #1205 failed with stages
in 18 minutes and 38 seconds
This diff is collapsed.
......@@ -327,11 +327,11 @@ impl MuFunctionVersion {
match callee.v {
TreeNode_::Instruction(_) => {}
TreeNode_::Value(ref pv) => {
match pv.v {
Value_::Constant(Constant::FuncRef(id)) => {
match &pv.v {
&Value_::Constant(Constant::FuncRef(ref func)) => {
ret.insert(
inst.id(),
(id, inst.has_exception_clause())
(func.id(), inst.has_exception_clause())
);
}
_ => {}
......@@ -1103,8 +1103,8 @@ impl Value {
}
}
const DISPLAY_ID: bool = true;
const DISPLAY_TYPE: bool = true;
const DISPLAY_ID: bool = false;
const DISPLAY_TYPE: bool = false;
const PRINT_ABBREVIATE_NAME: bool = true;
impl fmt::Debug for Value {
......@@ -1117,17 +1117,17 @@ impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if DISPLAY_TYPE {
match self.v {
Value_::SSAVar(_) => write!(f, "{}(%{})", self.ty, self.hdr),
Value_::Constant(ref c) => write!(f, "{}({})", self.ty, c),
Value_::Global(ref ty) => write!(f, "{}(@{})", ty, self.hdr),
Value_::Memory(ref mem) => write!(f, "%{}{})", self.hdr, mem)
Value_::SSAVar(_) => write!(f, "<{}>{}", self.ty, self.hdr),
Value_::Constant(ref c) => write!(f, "<{}>{}", self.ty, c),
Value_::Global(ref ty) => write!(f, "<{}>@{}", ty, self.hdr),
Value_::Memory(ref mem) => write!(f, "<{}>{}{}", self.ty, self.hdr, mem)
}
} else {
match self.v {
Value_::SSAVar(_) => write!(f, "%{}", self.hdr),
Value_::Constant(ref c) => write!(f, "{}", c),
Value_::SSAVar(_) => write!(f, "{}", self.hdr),
Value_::Constant(ref c) => write!(f, "<{}>{}", self.ty, c),
Value_::Global(_) => write!(f, "@{}", self.hdr),
Value_::Memory(ref mem) => write!(f, "%{}{}", self.hdr, mem)
Value_::Memory(ref mem) => write!(f, "{}{}", self.hdr, mem)
}
}
}
......@@ -1232,7 +1232,7 @@ pub enum Constant {
/// double constants
Double(f64),
/// function reference
FuncRef(MuID),
FuncRef(MuEntityHeader),
/// vector constant (currently not used)
Vector(Vec<Constant>),
/// null reference
......@@ -1250,12 +1250,20 @@ impl fmt::Display for Constant {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Constant::Int(v) => write!(f, "{}", v as i64),
&Constant::IntEx(ref v) => write!(f, "IntEx {:?}", v),
&Constant::IntEx(ref v) => {
let mut res = format!("");
// Stored in little-endian order, but we need to display it in big-endian order
for i in 1 .. v.len() + 1 {
res.push_str(format!("{:016X}", v[v.len() - i]).to_string().as_str());
}
write!(f, "0x{}", res)
},
&Constant::Float(v) => write!(f, "{}", v),
&Constant::Double(v) => write!(f, "{}", v),
// &Constant::IRef(v) => write!(f, "{}", v),
&Constant::FuncRef(v) => write!(f, "FuncRef {}", v),
&Constant::FuncRef(ref v) => write!(f, "FuncRef {}", v.name),
&Constant::Vector(ref v) => {
// TODO: Make this Muc compatible?
write!(f, "[").unwrap();
for i in 0..v.len() {
write!(f, "{}", v[i]).unwrap();
......@@ -1265,8 +1273,8 @@ impl fmt::Display for Constant {
}
write!(f, "]")
}
&Constant::NullRef => write!(f, "NullRef"),
&Constant::ExternSym(ref name) => write!(f, "ExternSym({})", name),
&Constant::NullRef => write!(f, "NULL"),
&Constant::ExternSym(ref name) => write!(f, "EXTERN \\\"{}\\\"", name),
&Constant::List(ref vec) => {
write!(f, "List(").unwrap();
......@@ -1569,21 +1577,7 @@ impl MuEntityHeader {
/// an abbreviate (easy reading) version of the name
fn abbreviate_name(&self) -> String {
let split: Vec<&str> = self.name.split('.').collect();
let mut ret = "".to_string();
for i in 0..split.len() - 1 {
ret.push(match split[i].chars().next() {
Some(c) => c,
None => '_'
});
ret.push('.');
}
ret.push_str(split.last().unwrap());
ret
self.name.split('.').last().unwrap().to_string()
}
pub fn clone_with_id(&self, new_id: MuID) -> MuEntityHeader {
......
......@@ -11,8 +11,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#[derive(Copy, Clone, Debug, PartialEq)]
use std::fmt;
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum BinOp {
// BinOp Int(n) Int(n) -> Int(n)
Add,
......@@ -38,6 +38,11 @@ pub enum BinOp {
FDiv,
FRem
}
impl fmt::Display for BinOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", format!("{:?}", self).to_uppercase())
}
}
impl BinOp {
pub fn is_fp(self) -> bool {
......@@ -80,6 +85,11 @@ pub enum CmpOp {
FUNE,
FUNO
}
impl fmt::Display for CmpOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl CmpOp {
/// returns the CmpOp X for CmpOp Y, such that (a Y b) is equivalent to (b X a)
......@@ -225,6 +235,11 @@ pub enum ConvOp {
REFCAST,
PTRCAST
}
impl fmt::Display for ConvOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AtomicRMWOp {
......@@ -240,3 +255,9 @@ pub enum AtomicRMWOp {
UMAX,
UMIN
}
impl fmt::Display for AtomicRMWOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
......@@ -390,6 +390,14 @@ impl MuType {
}
}
/// gets the signature of a funcref or ufuncptr type
pub fn get_sig(&self) -> Option<P<MuFuncSig>> {
match self.v {
MuType_::FuncRef(ref sig) | MuType_::UFuncPtr(ref sig)=> Some(sig.clone()),
_ => None
}
}
/// gets a field's type of a struct type,
/// returns None if the type is not a struct or hybrid type
pub fn get_field_ty(&self, index: usize) -> Option<P<MuType>> {
......@@ -540,9 +548,9 @@ impl fmt::Display for MuType_ {
&MuType_::Tagref64 => write!(f, "tagref64"),
&MuType_::Vector(ref ty, size) => write!(f, "vector<{} {}>", ty, size),
&MuType_::FuncRef(ref sig) => write!(f, "funcref<{}>", sig),
&MuType_::UFuncPtr(ref sig) => write!(f, "ufuncref<{}>", sig),
&MuType_::Struct(ref tag) => write!(f, "{}(struct)", tag),
&MuType_::Hybrid(ref tag) => write!(f, "{}(hybrid)", tag)
&MuType_::UFuncPtr(ref sig) => write!(f, "ufuncptr<{}>", sig),
&MuType_::Struct(ref tag) => write!(f, "{}", tag),
&MuType_::Hybrid(ref tag) => write!(f, "{}", tag)
}
}
}
......@@ -643,7 +651,7 @@ impl fmt::Display for HybridType_ {
write!(f, " ").unwrap();
}
}
write!(f, "|{}>", self.var_ty)
write!(f, " {}>", self.var_ty)
}
}
......@@ -820,8 +828,8 @@ rodal_struct!(MuFuncSig{hdr, ret_tys, arg_tys});
impl fmt::Display for MuFuncSig {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}] -> [{}]",
vec_utils::as_str(&self.arg_tys), vec_utils::as_str(&self.ret_tys))
write!(f, "({})->({})",
vec_utils::as_str_sp(&self.arg_tys), vec_utils::as_str_sp(&self.ret_tys))
}
}
......
......@@ -37,6 +37,7 @@ use std::usize;
use std::ops;
use std::collections::HashSet;
use std::sync::RwLock;
use compiler::backend::code_emission::{emit_mu_types, emit_mu_globals};
macro_rules! trace_emit {
($arg1:tt $($arg:tt)*) => {
......@@ -3644,6 +3645,9 @@ pub fn emit_context_with_reloc(
use std::path;
use std::io::prelude::*;
emit_mu_types("", vm);
emit_mu_globals("", vm);
debug!("---Emit VM Context---");
create_emit_directory(vm);
......
......@@ -145,7 +145,7 @@ impl<'a> InstructionSelection {
self.process_dest(&ops, fallthrough_dest, f_content, f_context, vm);
self.process_dest(&ops, branch_dest, f_content, f_context, vm);
let branch_target = f_content.get_block(branch_dest.target).name();
let branch_target = f_content.get_block(branch_dest.target.id()).name();
let ref cond = ops[cond];
......@@ -311,7 +311,7 @@ impl<'a> InstructionSelection {
self.process_dest(&ops, dest, f_content, f_context, vm);
let target = f_content.get_block(dest.target).name();
let target = f_content.get_block(dest.target.id()).name();
trace!("emit branch1");
// jmp
......@@ -339,7 +339,7 @@ impl<'a> InstructionSelection {
// process dest
self.process_dest(&ops, case_dest, f_content, f_context, vm);
let target = f_content.get_block(case_dest.target).name();
let target = f_content.get_block(case_dest.target.id()).name();
let mut imm_val = 0 as u64;
// Is one of the arguments a valid immediate?
......@@ -375,7 +375,7 @@ impl<'a> InstructionSelection {
// emit default
self.process_dest(&ops, default, f_content, f_context, vm);
let default_target = f_content.get_block(default.target).name();
let default_target = f_content.get_block(default.target.id()).name();
self.backend.emit_b(default_target);
} else {
panic!("expecting cond in switch to be ireg: {}", cond);
......@@ -4687,7 +4687,7 @@ impl<'a> InstructionSelection {
f_content: &FunctionContent
) -> Option<MuName> {
if resumption.is_some() {
let target_id = resumption.unwrap().exn_dest.target;
let target_id = resumption.unwrap().exn_dest.target.id();
Some(f_content.get_block(target_id).name())
} else {
None
......@@ -4700,13 +4700,13 @@ impl<'a> InstructionSelection {
callsite: ValueLocation,
stack_arg_size: usize
) {
let target_block = match resumption {
Some(rd) => rd.exn_dest.target,
let target_block_id = match resumption {
Some(rd) => rd.exn_dest.target.id(),
None => 0
};
self.current_callsites
.push_back((callsite.to_relocatable(), target_block, stack_arg_size));
.push_back((callsite.to_relocatable(), target_block_id, stack_arg_size));
}
fn emit_mu_call(
......@@ -4853,9 +4853,7 @@ impl<'a> InstructionSelection {
);
if resumption.is_some() {
let ref normal_dest = resumption.as_ref().unwrap().normal_dest;
let normal_target_name = f_content.get_block(normal_dest.target).name();
self.backend.emit_b(normal_target_name);
self.backend.emit_b(resumption.as_ref().unwrap().normal_dest.target.name());
}
}
}
......@@ -4890,7 +4888,7 @@ impl<'a> InstructionSelection {
// }
//
let ref target_args = f_content
.get_block(dest.target)
.get_block(dest.target.id())
.content
.as_ref()
.unwrap()
......@@ -5832,8 +5830,8 @@ impl<'a> InstructionSelection {
fn node_funcref_const_to_id(&mut self, op: &TreeNode) -> MuID {
match op.v {
TreeNode_::Value(ref pv) => {
match pv.v {
Value_::Constant(Constant::FuncRef(id)) => id,
match &pv.v {
&Value_::Constant(Constant::FuncRef(ref hdr)) => hdr.id(),
_ => panic!("expected a funcref const")
}
}
......
......@@ -2061,11 +2061,11 @@ pub fn emit_ireg_value(
tmp
}
&Constant::FuncRef(func_id) => {
&Constant::FuncRef(ref func) => {
let tmp = make_temporary(f_context, pv.ty.clone(), vm);
let mem =
make_value_symbolic(vm.get_name_for_func(func_id), true, &ADDRESS_TYPE, vm);
make_value_symbolic(vm.get_name_for_func(func.id()), true, &ADDRESS_TYPE, vm);
emit_calculate_address(backend, &tmp, &mem, vm);
tmp
}
......@@ -2746,7 +2746,7 @@ fn emit_move_value_to_value(
emit_mov_u64(backend, dest, imm);
} else if src.is_func_const() {
let func_id = match src.v {
Value_::Constant(Constant::FuncRef(id)) => id,
Value_::Constant(Constant::FuncRef(ref func)) => func.id(),
_ => unreachable!()
};
let mem =
......
......@@ -4143,7 +4143,7 @@ pub fn emit_sym_table(vm: &VM) {
use std::collections::HashMap;
use compiler::backend::code_emission::emit_mu_types;
use compiler::backend::code_emission::{emit_mu_types, emit_mu_globals};
/// emit vm context for current session, considering relocation symbols/fields from the client
pub fn emit_context_with_reloc(
......@@ -4155,6 +4155,7 @@ pub fn emit_context_with_reloc(
use std::io::prelude::*;
emit_mu_types("", vm);
emit_mu_globals("", vm);
// creates emit directy, and file
debug!("---Emit VM Context---");
......
......@@ -231,7 +231,7 @@ impl<'a> InstructionSelection {
self.process_dest(&ops, fallthrough_dest, f_content, f_context, vm);
self.process_dest(&ops, branch_dest, f_content, f_context, vm);
let branch_target = f_content.get_block(branch_dest.target).name();
let branch_target = f_content.get_block(branch_dest.target.id()).name();
let ref cond = ops[cond];
if self.match_cmp_res(cond) {
......@@ -539,7 +539,7 @@ impl<'a> InstructionSelection {
self.process_dest(&ops, dest, f_content, f_context, vm);
let target = f_content.get_block(dest.target).name();
let target = f_content.get_block(dest.target.id()).name();
// jmp
self.backend.emit_jmp(target);
}
......@@ -567,7 +567,7 @@ impl<'a> InstructionSelection {
// process dest
self.process_dest(&ops, case_dest, f_content, f_context, vm);
let target = f_content.get_block(case_dest.target).name();
let target = f_content.get_block(case_dest.target.id()).name();
if self.match_iimm(case_op) {
let imm = self.node_iimm_to_i32(case_op);
......@@ -602,7 +602,7 @@ impl<'a> InstructionSelection {
// emit default
self.process_dest(&ops, default, f_content, f_context, vm);
let default_target = f_content.get_block(default.target).name();
let default_target = f_content.get_block(default.target.id()).name();
self.backend.emit_jmp(default_target);
} else {
// other EQ-comparable types, e.g. floating point
......@@ -4473,7 +4473,7 @@ impl<'a> InstructionSelection {
// check if this call has exception clause - need to tell backend about this
let potentially_excepting = {
if resumption.is_some() {
let target_id = resumption.unwrap().exn_dest.target;
let target_id = resumption.unwrap().exn_dest.target.id();
Some(f_content.get_block(target_id).name())
} else {
None
......@@ -4531,10 +4531,10 @@ impl<'a> InstructionSelection {
if resumption.is_some() {
// record exception branch
let ref exn_dest = resumption.as_ref().unwrap().exn_dest;
let target_block = exn_dest.target;
let target_block_id = exn_dest.target.id();
self.current_callsites
.push_back((callsite.to_relocatable(), target_block, stack_arg_size));
.push_back((callsite.to_relocatable(), target_block_id, stack_arg_size));
// insert an intermediate block to branch to normal
// the branch is inserted later (because we need to deal with postcall convention)
......@@ -4558,10 +4558,7 @@ impl<'a> InstructionSelection {
// jump to target block
if resumption.is_some() {
let ref normal_dest = resumption.as_ref().unwrap().normal_dest;
let normal_target_name = f_content.get_block(normal_dest.target).name();
self.backend.emit_jmp(normal_target_name);
self.backend.emit_jmp(resumption.as_ref().unwrap().normal_dest.target.name());
}
}
......@@ -4713,7 +4710,7 @@ impl<'a> InstructionSelection {
// arguments are ready, we are starting continuation
let potential_exception_dest = match resumption {
Some(ref resumption) => {
let target_id = resumption.exn_dest.target;
let target_id = resumption.exn_dest.target.id();
Some(f_content.get_block(target_id).name())
}
None => None
......@@ -4763,7 +4760,7 @@ impl<'a> InstructionSelection {
if !is_kill {
// record this callsite
let target_block_id = match resumption {
Some(resumption) => resumption.exn_dest.target,
Some(resumption) => resumption.exn_dest.target.id(),
None => 0
};
self.current_callsites
......@@ -4868,7 +4865,7 @@ impl<'a> InstructionSelection {
&DestArg::Normal(op_index) => {
let ref arg = ops[op_index];
let ref target_args = f_content
.get_block(dest.target)
.get_block(dest.target.id())
.content
.as_ref()
.unwrap()
......@@ -5399,18 +5396,18 @@ impl<'a> InstructionSelection {
self.backend.emit_mov_r64_imm64(&tmp_h, vals[1] as i64);
}
// a function reference, loads the funcref to a temporary
&Constant::FuncRef(func_id) => {
&Constant::FuncRef(ref func) => {
// our code for linux has one more level of indirection
// so we need a load for linux
// sel4-rumprun is the same as Linux here
if cfg!(feature = "sel4-rumprun") {
let mem = self.get_mem_for_funcref(func_id, vm);
let mem = self.get_mem_for_funcref(func.id(), vm);
self.backend.emit_mov_r_mem(&tmp, &mem);
} else if cfg!(target_os = "macos") {
let mem = self.get_mem_for_funcref(func_id, vm);
let mem = self.get_mem_for_funcref(func.id(), vm);
self.backend.emit_lea_r64(&tmp, &mem);
} else if cfg!(target_os = "linux") {
let mem = self.get_mem_for_funcref(func_id, vm);
let mem = self.get_mem_for_funcref(func.id(), vm);
self.backend.emit_mov_r_mem(&tmp, &mem);
} else {
unimplemented!()
......@@ -6220,8 +6217,8 @@ impl<'a> InstructionSelection {
fn node_funcref_const_to_id(&mut self, op: &TreeNode) -> MuID {
match op.v {
TreeNode_::Value(ref pv) => {
match pv.v {
Value_::Constant(Constant::FuncRef(id)) => id,
match &pv.v {
&Value_::Constant(Constant::FuncRef(ref hdr)) => hdr.id(),
_ => panic!("expected a funcref const")
}
}
......
......@@ -96,7 +96,7 @@ pub fn emit_mu_types(suffix: &str, vm: &VM) {
let mut file_path = path::PathBuf::new();
file_path.push(&vm.vm_options.flag_aot_emit_dir);
file_path.push("___types".to_string() + suffix + ".muty");
file_path.push("___types".to_string() + suffix + ".uir");
let mut file = match File::create(file_path.as_path()) {
Err(why) => {
panic!(
......@@ -117,20 +117,20 @@ pub fn emit_mu_types(suffix: &str, vm: &VM) {
for ty in ty_guard.values() {
if ty.is_struct() {
write!(file, "{}", ty).unwrap();
write!(file, ".typedef {} = ", ty.hdr).unwrap();
let struct_ty = struct_map
.get(&ty.get_struct_hybrid_tag().unwrap())
.unwrap();
writeln!(file, " -> {}", struct_ty).unwrap();
writeln!(file, " {}", vm.get_backend_type_info(ty.id())).unwrap();
writeln!(file, "{}", struct_ty).unwrap();
writeln!(file, "\n\t/*{}*/", vm.get_backend_type_info(ty.id())).unwrap();
} else if ty.is_hybrid() {
write!(file, "{}", ty).unwrap();
let hybrid_ty = hybrid_map
.get(&ty.get_struct_hybrid_tag().unwrap())
.unwrap();
writeln!(file, " -> {}", hybrid_ty).unwrap();
writeln!(file, " {}", vm.get_backend_type_info(ty.id())).unwrap();
writeln!(file, "{}", hybrid_ty).unwrap();
writeln!(file, "\n\t/*{}*/", vm.get_backend_type_info(ty.id())).unwrap();
} else {
// we only care about struct
}
......@@ -141,6 +141,33 @@ pub fn emit_mu_types(suffix: &str, vm: &VM) {
}
}
pub fn emit_mu_globals(suffix: &str, vm: &VM) {
if EMIT_MUIR {
create_emit_directory(vm);
let mut file_path = path::PathBuf::new();
file_path.push(&vm.vm_options.flag_aot_emit_dir);
file_path.push("___globals".to_string() + suffix + ".uir");
let mut file = match File::create(file_path.as_path()) {
Err(why) => {
panic!(
"couldn't create mu globals file {}: {}",
file_path.to_str().unwrap(),
why
)
}
Ok(file) => file
};
let global_guard = vm.globals().read().unwrap();
for g in global_guard.values() {
write!(file, ".global {}<{}>", g.name(), g.ty.get_referent_ty().unwrap()).unwrap();
}
}
}
fn emit_mc_dot(func: &MuFunctionVersion, vm: &VM) {
let func_name = func.name();
......
......@@ -96,6 +96,7 @@ impl CompilerPolicy {
impl Default for CompilerPolicy {
fn default() -> Self {
let mut passes: Vec<Box<CompilerPass>> = vec![];
passes.push(Box::new(passes::UIRGen::new("")));
passes.push(Box::new(passes::DotGen::new(".orig")));
// ir level passes
......
......@@ -148,8 +148,8 @@ fn dfs(cur: MuID, stack: &mut Vec<MuID>, visited: &mut Vec<MuID>, func: &mut MuF
Branch1(ref dest) => {
vec![
BlockEdge {
target: dest.target,
kind: check_edge_kind(dest.target, stack),
target: dest.target.id(),
kind: check_edge_kind(dest.target.id(), stack),
is_exception: false,
probability: 1.0f32
},
......@@ -165,14 +165,14 @@ fn dfs(cur: MuID, stack: &mut Vec<MuID>, visited: &mut Vec<MuID>, func: &mut MuF
} => {
vec![
BlockEdge {
target: true_dest.target,
kind: check_edge_kind(true_dest.target, stack),
target: true_dest.target.id(),
kind: check_edge_kind(true_dest.target.id(), stack),
is_exception: false,
probability: true_prob
},
BlockEdge {
target: false_dest.target,
kind: check_edge_kind(false_dest.target, stack),
target: false_dest.target.id(),
kind: check_edge_kind(false_dest.target.id(), stack),
is_exception: false,
probability: 1.0f32 - true_prob
},
......@@ -211,11 +211,11 @@ fn dfs(cur: MuID, stack: &mut Vec<MuID>, visited: &mut Vec<MuID>, func: &mut MuF
};
for &(_, ref dest) in branches.iter() {
let target = dest.target;
check_add_edge(&mut ret, target, switch_prob);
let target_id = dest.target.id();
check_add_edge(&mut ret, target_id, switch_prob);
}
check_add_edge(&mut ret, default.target, BRANCH_DEFAULT_PROB);
check_add_edge(&mut ret, default.target.id(), BRANCH_DEFAULT_PROB);
ret
};
......@@ -240,14 +240,14 @@ fn dfs(cur: MuID, stack: &mut Vec<MuID>, visited: &mut Vec<MuID>, func: &mut MuF
// unconditional trap
vec![
BlockEdge {
target: normal.target,
kind: check_edge_kind(normal.target, stack),
target: normal.target.id(),
kind: check_edge_kind(normal.target.id(), stack),
is_exception: false,
probability: 1.0f32 * NORMAL_RESUME_CHANCE
},
BlockEdge {
target: exn.target,
kind: check_edge_kind(exn.target, stack),
target: exn.target.id(),
kind: check_edge_kind(exn.target.id(), stack),
is_exception: true,
probability: 1.0f32 * EXN_RESUME_CHANCE
},
......@@ -256,24 +256,24 @@ fn dfs(cur: MuID, stack: &mut Vec<MuID>, visited: &mut Vec<MuID>, func: &mut MuF
// watchpoint. jump to disable_dest when disabled. otherwise trap
vec![
BlockEdge {
target: disable_dest.as_ref().unwrap().target,
target: disable_dest.as_ref().unwrap().target.id(),
kind: check_edge_kind(
disable_dest.as_ref().unwrap().target,
disable_dest.as_ref().unwrap().target.id(),
stack
),
is_exception: false,
probability: WATCHPOINT_DISABLED_CHANCE
},
BlockEdge {
target: normal.target,
kind: check_edge_kind(normal.target, stack),
target: normal.target.id(),
kind: check_edge_kind(normal.target.id(), stack),
is_exception: false,
probability: (1.0f32 - WATCHPOINT_DISABLED_CHANCE) *
NORMAL_RESUME_CHANCE
},
BlockEdge {
target: exn.target,
kind: check_edge_kind(exn.target, stack),
target: exn.target.id(),
kind: check_edge_kind(exn.target.id(), stack),
is_exception: true,
probability: (1.0f32 - WATCHPOINT_DISABLED_CHANCE) *
EXN_RESUME_CHANCE
......@@ -290,14 +290,14 @@ fn dfs(cur: MuID, stack: &mut Vec<MuID>, visited: &mut Vec<MuID>, func: &mut MuF
} => {
vec![
BlockEdge {
target: disable_dest.target,
kind: check_edge_kind(disable_dest.target, stack),
target: disable_dest.target.id(),
kind: check_edge_kind(disable_dest.target.id(), stack),
is_exception: false,
probability: WATCHPOINT_DISABLED_CHANCE
},
BlockEdge {
target: enable_dest.target,
kind: check_edge_kind(enable_dest.target, stack),
target: enable_dest.target.id(),
kind: check_edge_kind(enable_dest.target.id(), stack),
is_exception: false,
probability: 1.0f32 - WATCHPOI