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.7% of users enabled 2FA.

Commit 223c9d0e authored by qinsoon's avatar qinsoon
Browse files

we should not coalesce a temporary with an unusable regsiter

parent 7c03955f
......@@ -273,6 +273,16 @@ impl MuFunctionVersion {
})
}
pub fn new_machine_reg(&mut self, v: P<Value>) -> P<TreeNode> {
self.context
.values
.insert(v.id(), SSAVarEntry::new(v.clone()));
P(TreeNode {
v: TreeNode_::Value(v)
})
}
pub fn new_constant(&mut self, v: P<Value>) -> P<TreeNode> {
P(TreeNode {
v: TreeNode_::Value(v)
......
......@@ -493,7 +493,7 @@ impl<'a> GraphColoring<'a> {
// if they are not from the same register group, we cannot coalesce them
if self.ig.get_group_of(m.from) != self.ig.get_group_of(m.to) {
info!("a move instruction of two temporaries of different reigsters group");
info!("a move instruction of two temporaries of different register groups");
info!("from: {:?}, to: {:?}", m.from, m.to);
return;
......@@ -532,6 +532,22 @@ impl<'a> GraphColoring<'a> {
precolored_v
);
// if u or v is a machine register that is not usable/not a color, we cannot coalesce
if self.precolored.contains(&u) {
let reg_u = self.ig.get_temp_of(u);
let group = backend::pick_group_for_reg(reg_u);
if !self.colors.get(&group).unwrap().contains(&reg_u) {
return;
}
}
if self.precolored.contains(&v) {
let reg_v = self.ig.get_temp_of(v);
let group = backend::pick_group_for_reg(reg_v);
if !self.colors.get(&group).unwrap().contains(&reg_v) {
return;
}
}
if u == v {
trace!("u == v, coalesce the move");
self.coalesced_moves.insert(m);
......
......@@ -192,6 +192,12 @@ macro_rules! ssa {
}
}
macro_rules! machine_reg {
(($vm: expr, $fv: ident) $name: ident = $mreg: expr) => {
let $name = $fv.new_machine_reg($mreg.clone());
}
}
macro_rules! consta {
(($vm: expr, $fv: ident) $name: ident = $c: ident) => {
let $name = $fv.new_constant($c.clone());
......
......@@ -18,6 +18,7 @@ extern crate libloading;
use mu::linkutils;
use mu::linkutils::aot;
use mu::utils::LinkedHashMap;
use mu::compiler::backend::x86_64;
use test_compiler::test_call::gen_ccall_exit;
use self::mu::compiler::*;
use self::mu::ast::ir::*;
......@@ -2038,3 +2039,74 @@ fn spill_int8() -> VM {
vm
}
#[test]
#[cfg(target_arch = "x86_64")]
fn test_coalesce_unusable_reg() {
VM::start_logging_trace();
let vm = coalesce_unusable_reg();
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("coalesce_unusable_reg");
{
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
let compiled_funcs = vm.compiled_funcs().read().unwrap();
let cf_lock = compiled_funcs.get(&func_ver.id()).unwrap();
let cf = cf_lock.read().unwrap();
let x_id = vm.id_of("x");
// x exists
assert!(cf.temps.contains_key(&x_id));
// x is not rsp
let x_color = *cf.temps.get(&x_id).unwrap();
println!("x is assigned to {}", x_color);
assert!(x_color != x86_64::RSP.id());
}
}
#[cfg(target_arch = "x86_64")]
fn coalesce_unusable_reg() -> VM {
let vm = VM::new();
typedef! ((vm) int64 = mu_int(64));
funcsig! ((vm) sig = () -> (int64));
funcdecl! ((vm) <sig> coalesce_unusable_reg);
funcdef! ((vm) <sig> coalesce_unusable_reg VERSION coalesce_unusable_reg_v1);
block! ((vm, coalesce_unusable_reg_v1) blk_entry);
ssa! ((vm, coalesce_unusable_reg_v1) <int64> x);
machine_reg!((vm, coalesce_unusable_reg_v1) rsp = x86_64::RSP);
inst! ((vm, coalesce_unusable_reg_v1) blk_entry_mov:
MOVE rsp -> x
);
inst! ((vm, coalesce_unusable_reg_v1) blk_entry_ret:
RET (x)
);
define_block!((vm, coalesce_unusable_reg_v1) blk_entry() {
blk_entry_mov,
blk_entry_ret
});
define_func_ver!((vm) coalesce_unusable_reg_v1 (entry: blk_entry) {
blk_entry
});
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