Commit ef135dc0 authored by qinsoon's avatar qinsoon

[wip] continue working on liveness. need more tests

parent 8669dba8
......@@ -2,7 +2,7 @@ use ast::ptr::P;
use ast::types::*;
use ast::inst::*;
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum OpCode {
// SSA
RegI64,
......@@ -112,7 +112,7 @@ pub fn pick_op_code_for_const(ty: &P<MuType>) -> OpCode {
}
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n)
Add,
......@@ -138,7 +138,7 @@ pub enum BinOp {
FRem
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum CmpOp {
// for Int comparison
EQ,
......@@ -171,7 +171,7 @@ pub enum CmpOp {
FUNO
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AtomicRMWOp {
XCHG,
ADD,
......
......@@ -63,7 +63,9 @@ impl MachineCode for ASMCode {
let n_insts = self.code.len();
for i in 0..n_insts {
let ref line = self.code[i];
println!("#{}\t{}\t\tpred: {:?}, succ: {:?}", i, line.code, self.preds[i], self.succs[i]);
println!("#{}\t{:30}\t\tdefine: {:?}\tuses: {:?}\tpred: {:?}\tsucc: {:?}",
i, line.code, self.get_inst_reg_defines(i), self.get_inst_reg_uses(i),
self.preds[i], self.succs[i]);
}
println!("");
......@@ -252,9 +254,9 @@ impl ASMCodeGen {
loc.line = line;
if mc.reg_uses.contains_key(&id) {
mc.reg_defines.get_mut(&id).unwrap().push(loc.clone());
mc.reg_uses.get_mut(&id).unwrap().push(loc.clone());
} else {
mc.reg_defines.insert(id, vec![loc.clone()]);
mc.reg_uses.insert(id, vec![loc.clone()]);
}
}
......@@ -466,16 +468,16 @@ impl CodeGenerator for ASMCodeGen {
fn emit_mov_r64_imm32(&mut self, dest: &P<Value>, src: u32) {
trace!("emit: mov {} -> {}", src, dest);
let (reg1, id1, loc1) = self.prepare_op(dest, 4 + 1);
let (reg1, id1, loc1) = self.prepare_op(dest, 4 + 1 + 1 + src.to_string().len() + 1);
let asm = format!("movq {} ${}", src, reg1);
let asm = format!("movq ${} {}", src, reg1);
self.add_asm_inst(
asm,
vec![],
vec![],
vec![id1],
vec![loc1]
vec![loc1],
vec![],
vec![]
)
}
......@@ -708,15 +710,16 @@ impl CodeGenerator for ASMCodeGen {
trace!("emit: push {}", src);
let (reg, id, loc) = self.prepare_op(src, 5 + 1);
let rsp = self.prepare_machine_reg(&x86_64::RSP);
let asm = format!("pushq {}", reg);
self.add_asm_inst(
asm,
vec![rsp],
vec![],
vec![],
vec![id],
vec![loc]
vec![rsp],
vec![]
)
}
......@@ -724,14 +727,15 @@ impl CodeGenerator for ASMCodeGen {
trace!("emit: pop {}", dest);
let (reg, id, loc) = self.prepare_op(dest, 4 + 1);
let rsp = self.prepare_machine_reg(&x86_64::RSP);
let asm = format!("popq {}", reg);
self.add_asm_inst(
asm,
vec![id],
vec![id, rsp],
vec![loc.clone()],
vec![id],
vec![id, rsp],
vec![loc]
)
}
......
......@@ -87,16 +87,52 @@ impl InterferenceGraph {
self.matrix.as_ref().unwrap()[(from_ix, to_ix)]
}
pub fn print_with(&self, func: &MuFunction) {
pub fn print(&self) {
println!("");
println!("Interference Graph");
println!("color:");
for (n, c) in self.color.iter() {
println!("Node {} -> Color {}", n, c);
}
println!("moves:");
for mov in self.moves.iter() {
println!("Move {} -> {}", mov.0, mov.1);
}
println!("graph:");
{
let idx_to_node_id = {
let mut ret : HashMap<MatrixIndex, MuID> = HashMap::new();
for node_id in self.nodes.keys() {
ret.insert(*self.nodes.get(node_id).unwrap(), *node_id);
}
ret
};
let matrix = self.matrix.as_ref().unwrap();
for i in 0..matrix.ncols() {
for j in 0..matrix.nrows() {
if matrix[(i, j)] {
let from_node = idx_to_node_id.get(&i).unwrap();
let to_node = idx_to_node_id.get(&j).unwrap();
println!("Node {} -> Node {}", from_node, to_node);
}
}
}
}
println!("");
}
#[allow(dead_code)]
pub fn print_symbols(&self, func: &MuFunction) {
let ref context = func.context;
println!("");
println!("Interference Graph");
println!("nodes:");
for (n, ix) in self.nodes.iter() {
println!("Node {} -> Index {}", get_tag(*n, context), ix);
}
println!("color:");
for (n, c) in self.color.iter() {
println!("Node {} -> Color {}", get_tag(*n, context), get_tag(*c, context));
......@@ -124,7 +160,7 @@ impl InterferenceGraph {
let from_node = idx_to_node_id.get(&i).unwrap();
let to_node = idx_to_node_id.get(&j).unwrap();
println!("{} -> {}", get_tag(*from_node, context), get_tag(*to_node, context));
println!("Node {} -> Node {}", get_tag(*from_node, context), get_tag(*to_node, context));
}
}
}
......@@ -142,7 +178,7 @@ fn is_machine_reg(node: MuID) -> bool {
}
// from tony's code src/RegAlloc/Liveness.java
pub fn build (cf: &CompiledFunction, f: &MuFunction) -> InterferenceGraph {
pub fn build (cf: &CompiledFunction) -> InterferenceGraph {
let mut ig = InterferenceGraph::new();
// move precolor nodes to later iteration of registers
......@@ -223,12 +259,17 @@ pub fn build (cf: &CompiledFunction, f: &MuFunction) -> InterferenceGraph {
let src = cf.mc.get_inst_reg_uses(n);
let dst = cf.mc.get_inst_reg_defines(n);
debug_assert!(src.len() == 1);
// src may be immediate number
// dest is definitly register
debug_assert!(dst.len() == 1);
ig.add_move(src[0], dst[0]);
Some(src[0])
if src.len() == 1 {
ig.add_move(src[0], dst[0]);
Some(src[0])
} else {
None
}
} else {
None
}
......
......@@ -28,7 +28,7 @@ impl CompilerPass for RegisterAllocation {
cf.mc.print();
let liveness = liveness::build(&mut cf, func);
liveness.print_with(func);
let liveness = liveness::build(&mut cf);
liveness.print();
}
}
\ 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