GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

Commit e91f7785 authored by qinsoon's avatar qinsoon

[wip] debugging. Some coloring choices are still wrong

parent def9deb3
#![allow(unused_variables)]
use compiler::backend;
use compiler::backend::x86_64;
use compiler::backend::x86_64::CodeGenerator;
use vm::machine_code::MachineCode;
use utils::string_utils;
use ast::ptr::P;
use ast::ir::*;
use ast::inst::*;
......@@ -56,6 +59,35 @@ impl MachineCode for ASMCode {
&self.code[index].defines
}
fn replace_reg(&mut self, from: MuID, to: MuID) {
let to_reg_tag : MuTag = backend::all_regs()[to].tag;
let to_reg_string = "%".to_string() + to_reg_tag;
match self.reg_defines.get(&from) {
Some(defines) => {
for loc in defines {
let ref mut inst_to_patch = self.code[loc.line];
for i in 0..loc.len {
string_utils::replace(&mut inst_to_patch.code, loc.index, &to_reg_string, to_reg_string.len());
}
}
},
None => {}
}
match self.reg_uses.get(&from) {
Some(uses) => {
for loc in uses {
let ref mut inst_to_patch = self.code[loc.line];
for i in 0..loc.len {
string_utils::replace(&mut inst_to_patch.code, loc.index, &to_reg_string, to_reg_string.len());
}
}
},
None => {}
}
}
fn print(&self) {
println!("");
......@@ -142,7 +174,7 @@ pub struct ASMCodeGen {
cur: Option<Box<ASMCode>>
}
const REG_PLACEHOLDER_LEN : usize = 3;
const REG_PLACEHOLDER_LEN : usize = 5;
lazy_static! {
pub static ref REG_PLACEHOLDER : String = {
let blank_spaces = [' ' as u8; REG_PLACEHOLDER_LEN];
......@@ -170,18 +202,6 @@ impl ASMCodeGen {
self.cur().code.len()
}
fn replace(s: &mut String, index: usize, replace: &str, replace_len: usize) {
let vec = unsafe {s.as_mut_vec()};
for i in 0..replace_len {
if i < replace.len() {
vec[index + i] = replace.as_bytes()[i] as u8;
} else {
vec[index + i] = ' ' as u8;
}
}
}
fn add_asm_block_label(&mut self, code: String, block_name: &'static str) {
let l = self.line();
self.cur_mut().code.push(ASM::symbolic(code));
......@@ -489,10 +509,10 @@ impl CodeGenerator for ASMCodeGen {
fn emit_mov_r64_r64(&mut self, dest: &P<Value>, src: &P<Value>) {
trace!("emit: mov {} -> {}", src, dest);
let (reg1, id1, loc1) = self.prepare_op(dest, 4 + 1);
let (reg2, id2, loc2) = self.prepare_op(src, 4 + 1 + reg1.len() + 1);
let (reg1, id1, loc1) = self.prepare_op(src, 4 + 1);
let (reg2, id2, loc2) = self.prepare_op(dest, 4 + 1 + reg1.len() + 1);
let asm = format!("movq {} {}", reg2, reg1);
let asm = format!("movq {} {}", reg1, reg2);
self.add_asm_inst(
asm,
......@@ -506,10 +526,10 @@ impl CodeGenerator for ASMCodeGen {
fn emit_add_r64_r64(&mut self, dest: &P<Value>, src: &P<Value>) {
trace!("emit: add {}, {} -> {}", dest, src, dest);
let (reg1, id1, loc1) = self.prepare_op(dest, 4 + 1);
let (reg2, id2, loc2) = self.prepare_op(src, 4 + 1 + reg1.len() + 1);
let (reg1, id1, loc1) = self.prepare_op(src, 4 + 1);
let (reg2, id2, loc2) = self.prepare_op(dest, 4 + 1 + reg1.len() + 1);
let asm = format!("addq {} {}", reg2, reg1);
let asm = format!("addq {} {}", reg1, reg2);
self.add_asm_inst(
asm,
......@@ -544,10 +564,10 @@ impl CodeGenerator for ASMCodeGen {
fn emit_sub_r64_r64(&mut self, dest: &P<Value>, src: &P<Value>) {
trace!("emit: sub {}, {} -> {}", dest, src, dest);
let (reg1, id1, loc1) = self.prepare_op(dest, 4 + 1);
let (reg2, id2, loc2) = self.prepare_op(src, 4 + 1 + reg1.len() + 1);
let (reg1, id1, loc1) = self.prepare_op(src, 4 + 1);
let (reg2, id2, loc2) = self.prepare_op(dest, 4 + 1 + reg1.len() + 1);
let asm = format!("subq {} {}", reg2, reg1);
let asm = format!("subq {} {}", reg1, reg2);
self.add_asm_inst(
asm,
......@@ -566,9 +586,9 @@ impl CodeGenerator for ASMCodeGen {
fn emit_sub_r64_imm32(&mut self, dest: &P<Value>, src: u32) {
trace!("emit: sub {}, {} -> {}", dest, 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!("subq {} ${}", src, reg1);
let asm = format!("subq ${} {}", src, reg1);
self.add_asm_inst(
asm,
......
......@@ -13,13 +13,12 @@ use std::collections::HashMap;
const COALESCING : bool = true;
pub struct GraphColoring <'a> {
ig: InterferenceGraph,
cur_cf: &'a CompiledFunction,
pub struct GraphColoring {
pub ig: InterferenceGraph,
precolored: HashSet<Node>,
colors: HashMap<backend::RegGroup, HashSet<MuID>>,
colored_nodes: Vec<Node>,
pub colored_nodes: Vec<Node>,
initial: Vec<Node>,
degree: HashMap<Node, isize>,
......@@ -43,11 +42,10 @@ pub struct GraphColoring <'a> {
select_stack: Vec<Node>
}
impl <'a> GraphColoring <'a> {
pub fn start (cf: &CompiledFunction, ig: InterferenceGraph) -> GraphColoring {
impl GraphColoring {
pub fn start (ig: InterferenceGraph) -> GraphColoring {
let mut coloring = GraphColoring {
ig: ig,
cur_cf: cf,
precolored: HashSet::new(),
colors: {
......@@ -359,7 +357,7 @@ impl <'a> GraphColoring <'a> {
}
}
fn get_alias(&self, node: Node) -> Node {
pub fn get_alias(&self, node: Node) -> Node {
if self.coalesced_nodes.contains(&node) {
self.get_alias(*self.alias.get(&node).unwrap())
} else {
......
......@@ -92,6 +92,14 @@ impl InterferenceGraph {
}
}
pub fn temps(&self) -> Vec<MuID>{
let mut ret = vec![];
for reg in self.nodes.keys() {
ret.push(*reg);
}
ret
}
pub fn nodes(&self) -> Vec<Node> {
let mut ret = vec![];
for node in self.nodes.values() {
......
......@@ -28,7 +28,7 @@ impl CompilerPass for RegisterAllocation {
#[allow(unused_variables)]
fn visit_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
let mut compiled_funcs = vm_context.compiled_funcs().read().unwrap();
let compiled_funcs = vm_context.compiled_funcs().read().unwrap();
let mut cf = compiled_funcs.get(func.fn_name).unwrap().borrow_mut();
cf.mc.print();
......@@ -39,7 +39,30 @@ impl CompilerPass for RegisterAllocation {
let liveness = liveness::build(&mut cf, func);
liveness.print();
let coloring = coloring::GraphColoring::start(&mut cf, liveness);
let coloring = coloring::GraphColoring::start(liveness);
let spills = coloring.spills();
if !spills.is_empty() {
unimplemented!();
}
// replace regs
trace!("Replacing Registers...");
for node in coloring.ig.nodes() {
let temp = coloring.ig.get_temp_of(node);
// skip machine registers
if temp < RESERVED_NODE_IDS_FOR_MACHINE {
continue;
} else {
let alias = coloring.get_alias(node);
let machine_reg = coloring.ig.get_color_of(alias).unwrap();
trace!("replacing {} with {}", temp, machine_reg);
cf.mc.replace_reg(temp, machine_reg);
}
}
cf.mc.print();
}
}
\ No newline at end of file
#![allow(dead_code)]
// This porvides some missing operations on Vec.
// They are not included in the standard libarary.
// (because they are likely inefficient?)
......@@ -45,4 +47,19 @@ pub mod hashset_utils {
set.take(&next)
}
}
}
pub mod string_utils {
pub fn replace(s: &mut String, index: usize, replace: &String, replace_len: usize) {
let vec = unsafe {s.as_mut_vec()};
let vec_replace = replace.as_bytes();
for i in 0..replace_len {
if i < replace.len() {
vec[index + i] = vec_replace[i] as u8;
} else {
vec[index + i] = ' ' as u8;
}
}
}
}
\ No newline at end of file
......@@ -16,4 +16,6 @@ pub trait MachineCode {
fn get_inst_reg_uses(&self, index: usize) -> &Vec<MuID>;
fn get_inst_reg_defines(&self, index: usize) -> &Vec<MuID>;
fn replace_reg(&mut self, from: MuID, to: MuID);
}
\ 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