Commit 89c1f1cb authored by qinsoon's avatar qinsoon

reformat code byy rustfmt

parent d1df3753
Pipeline #749 failed with stages
in 3 minutes and 12 seconds
// Copyright 2017 The Australian National University
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
......@@ -18,10 +18,12 @@ extern crate gcc;
#[cfg(target_arch = "x86_64")]
fn main() {
gcc::compile_library("libruntime_c.a", &["src/runtime/runtime_c_x64_sysv.c"]);
gcc::Config::new().flag("-O3").flag("-c")
.file("src/runtime/runtime_asm_x64_sysv.S")
.compile("libruntime_asm.a");
gcc::Config::new()
.flag("-O3")
.flag("-c")
.file("src/runtime/runtime_asm_x64_sysv.S")
.compile("libruntime_asm.a");
}
#[cfg(target_os = "linux")]
......@@ -29,7 +31,9 @@ fn main() {
fn main() {
gcc::compile_library("libruntime_c.a", &["src/runtime/runtime_c_aarch64_sysv.c"]);
gcc::Config::new().flag("-O3").flag("-c")
gcc::Config::new()
.flag("-O3")
.flag("-c")
.file("src/runtime/runtime_asm_aarch64_sysv.S")
.compile("libruntime_asm.a");
}
\ No newline at end of file
}
This diff is collapsed.
This diff is collapsed.
......@@ -36,7 +36,7 @@ pub enum BinOp {
FSub,
FMul,
FDiv,
FRem
FRem,
}
#[derive(Copy, Clone, Debug, PartialEq)]
......@@ -69,7 +69,7 @@ pub enum CmpOp {
FULT,
FULE,
FUNE,
FUNO
FUNO,
}
impl CmpOp {
......@@ -154,7 +154,7 @@ impl CmpOp {
SLT => ULT,
SGT => UGT,
SLE => ULE,
_ => self,
_ => self,
}
}
......@@ -162,32 +162,23 @@ impl CmpOp {
use op::CmpOp::*;
match self {
SGE | SLT | SGT | SLE => true,
_ => false
_ => false,
}
}
pub fn is_int_cmp(self) -> bool {
use op::CmpOp::*;
match self {
EQ
| NE
| SGE
| SGT
| SLE
| SLT
| UGE
| UGT
| ULE
| ULT => true,
_ => false
EQ | NE | SGE | SGT | SLE | SLT | UGE | UGT | ULE | ULT => true,
_ => false,
}
}
pub fn is_symmetric(self) -> bool {
use op::CmpOp::*;
match self {
EQ | NE | FORD| FUNO| FUNE | FUEQ | FONE | FOEQ => true,
_ => false
EQ | NE | FORD | FUNO | FUNE | FUEQ | FONE | FOEQ => true,
_ => false,
}
}
}
......@@ -205,7 +196,7 @@ pub enum ConvOp {
SITOFP,
BITCAST,
REFCAST,
PTRCAST
PTRCAST,
}
#[derive(Copy, Clone, Debug, PartialEq)]
......@@ -220,5 +211,5 @@ pub enum AtomicRMWOp {
MAX,
MIN,
UMAX,
UMIN
}
\ No newline at end of file
UMIN,
}
......@@ -23,4 +23,4 @@ pub type P<T> = Arc<T>;
/// Construct a `P<T>` from a `T` value.
pub fn P<T>(value: T) -> P<T> {
Arc::new(value)
}
\ No newline at end of file
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -47,11 +47,12 @@ use utils::LinkedHashMap;
use std::collections::HashMap;
// number of normal callee saved registers (excluding RSP and RBP)
pub const CALLEE_SAVED_COUNT : usize = 5;
pub const CALLEE_SAVED_COUNT: usize = 5;
/// a macro to declare a set of general purpose registers that are aliased to the first one
macro_rules! GPR_ALIAS {
($alias: ident: ($id64: expr, $r64: ident) -> $r32: ident, $r16: ident, $r8l: ident, $r8h: ident) => {
($alias: ident: ($id64: expr, $r64: ident) ->
$r32: ident, $r16: ident, $r8l: ident, $r8h: ident) => {
lazy_static!{
pub static ref $r64 : P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $r32 : P<Value> = GPR!($id64 +1, stringify!($r32), UINT32_TYPE);
......@@ -59,7 +60,8 @@ macro_rules! GPR_ALIAS {
pub static ref $r8l : P<Value> = GPR!($id64 +3, stringify!($r8l), UINT8_TYPE);
pub static ref $r8h : P<Value> = GPR!($id64 +4, stringify!($r8h), UINT8_TYPE);
pub static ref $alias : [P<Value>; 5] = [$r64.clone(), $r32.clone(), $r16.clone(), $r8l.clone(), $r8h.clone()];
pub static ref $alias : [P<Value>; 5] = [$r64.clone(), $r32.clone(), $r16.clone(),
$r8l.clone(), $r8h.clone()];
}
};
......@@ -70,15 +72,17 @@ macro_rules! GPR_ALIAS {
pub static ref $r16 : P<Value> = GPR!($id64 +2, stringify!($r16), UINT16_TYPE);
pub static ref $r8 : P<Value> = GPR!($id64 +3, stringify!($r8) , UINT8_TYPE );
pub static ref $alias : [P<Value>; 4] = [$r64.clone(), $r32.clone(), $r16.clone(), $r8.clone()];
pub static ref $alias : [P<Value>; 4] = [$r64.clone(), $r32.clone(),
$r16.clone(), $r8.clone()];
}
};
($alias: ident: ($id64: expr, $r64: ident)) => {
lazy_static!{
pub static ref $r64 : P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $r64 : P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $alias : [P<Value>; 4] = [$r64.clone(), $r64.clone(), $r64.clone(), $r64.clone()];
pub static ref $alias : [P<Value>; 4] = [$r64.clone(), $r64.clone(),
$r64.clone(), $r64.clone()];
}
};
}
......@@ -179,7 +183,7 @@ pub fn get_alias_for_length(id: MuID, length: usize) -> P<Value> {
if id < FPR_ID_START {
let vec = match GPR_ALIAS_TABLE.get(&id) {
Some(vec) => vec,
None => panic!("didnt find {} as GPR", id)
None => panic!("didnt find {} as GPR", id),
};
match length {
......@@ -188,7 +192,7 @@ pub fn get_alias_for_length(id: MuID, length: usize) -> P<Value> {
16 => vec[2].clone(),
8 => vec[3].clone(),
1 => vec[3].clone(),
_ => panic!("unexpected length {} for {}", length, vec[0])
_ => panic!("unexpected length {} for {}", length, vec[0]),
}
} else {
for r in ALL_FPRS.iter() {
......@@ -235,7 +239,7 @@ pub fn get_color_for_precolored(id: MuID) -> MuID {
if id < FPR_ID_START {
match GPR_ALIAS_LOOKUP.get(&id) {
Some(val) => val.id(),
None => panic!("cannot find GPR {}", id)
None => panic!("cannot find GPR {}", id),
}
} else {
// we do not have alias for FPRs
......@@ -250,9 +254,9 @@ pub fn check_op_len(op: &P<Value>) -> usize {
Some(64) => 64,
Some(32) => 32,
Some(16) => 16,
Some(8) => 8,
Some(1) => 8,
_ => panic!("unsupported register length for x64: {}", op.ty)
Some(8) => 8,
Some(1) => 8,
_ => panic!("unsupported register length for x64: {}", op.ty),
}
}
......@@ -320,7 +324,7 @@ lazy_static! {
];
}
pub const FPR_ID_START : usize = 100;
pub const FPR_ID_START: usize = 100;
lazy_static!{
// floating point registers, we use SSE registers
......@@ -496,7 +500,7 @@ lazy_static! {
}
/// creates context for each machine register in FunctionContext
pub fn init_machine_regs_for_func (func_context: &mut FunctionContext) {
pub fn init_machine_regs_for_func(func_context: &mut FunctionContext) {
for reg in ALL_MACHINE_REGS.values() {
let reg_id = reg.extract_ssa_id().unwrap();
let entry = SSAVarEntry::new(reg.clone());
......@@ -508,9 +512,9 @@ pub fn init_machine_regs_for_func (func_context: &mut FunctionContext) {
/// gets the number of registers in a certain register group
pub fn number_of_usable_regs_in_group(group: RegGroup) -> usize {
match group {
RegGroup::GPR => ALL_USABLE_GPRS.len(),
RegGroup::GPR => ALL_USABLE_GPRS.len(),
RegGroup::GPREX => ALL_USABLE_GPRS.len(),
RegGroup::FPR => ALL_USABLE_FPRS.len()
RegGroup::FPR => ALL_USABLE_FPRS.len(),
}
}
......@@ -574,9 +578,9 @@ pub fn get_callee_saved_offset(reg: MuID) -> isize {
let id = if reg == RBX.id() {
0
} else {
(reg - R12.id())/4 + 1
(reg - R12.id()) / 4 + 1
};
(id as isize + 1)*(-8)
(id as isize + 1) * (-8)
}
/// is a machine register (by ID) callee saved?
......@@ -597,10 +601,9 @@ pub fn is_valid_x86_imm(op: &P<Value>) -> bool {
if op.ty.get_int_length().is_some() && op.ty.get_int_length().unwrap() <= 32 {
match op.v {
Value_::Constant(Constant::Int(val)) if val as i32 >= i32::MIN && val as i32 <= i32::MAX => {
true
},
_ => false
Value_::Constant(Constant::Int(val))
if val as i32 >= i32::MIN && val as i32 <= i32::MAX => true,
_ => false,
}
} else {
false
......@@ -615,49 +618,53 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize {
match inst.v {
// simple
BinOp(_, _, _) => 1,
BinOp(_, _, _) => 1,
BinOpWithStatus(_, _, _, _) => 2,
CmpOp(_, _, _) => 1,
ConvOp{..} => 0,
CmpOp(_, _, _) => 1,
ConvOp { .. } => 0,
// control flow
Branch1(_) => 1,
Branch2{..} => 1,
Select{..} => 2,
Watchpoint{..} => 1,
WPBranch{..} => 2,
Switch{..} => 3,
Branch1(_) => 1,
Branch2 { .. } => 1,
Select { .. } => 2,
Watchpoint { .. } => 1,
WPBranch { .. } => 2,
Switch { .. } => 3,
// call
ExprCall{..} | ExprCCall{..} | Call{..} | CCall{..} => 5,
Return(_) => 1,
ExprCall { .. } | ExprCCall { .. } | Call { .. } | CCall { .. } => 5,
Return(_) => 1,
TailCall(_) => 1,
// memory access
Load{..} | Store{..} => 1,
CmpXchg{..} => 1,
AtomicRMW{..} => 1,
AllocA(_) => 1,
AllocAHybrid(_, _) => 1,
Fence(_) => 1,
Load { .. } | Store { .. } => 1,
CmpXchg { .. } => 1,
AtomicRMW { .. } => 1,
AllocA(_) => 1,
AllocAHybrid(_, _) => 1,
Fence(_) => 1,
// memory addressing
GetIRef(_) | GetFieldIRef{..} | GetElementIRef{..} | ShiftIRef{..} | GetVarPartIRef{..} => 0,
GetIRef(_) |
GetFieldIRef { .. } |
GetElementIRef { .. } |
ShiftIRef { .. } |
GetVarPartIRef { .. } => 0,
// runtime call
New(_) | NewHybrid(_, _) => 10,
NewStack(_) | NewThread(_, _) | NewThreadExn(_, _) | NewFrameCursor(_) => 10,
ThreadExit => 10,
Throw(_) => 10,
SwapStack{..} => 10,
ThreadExit => 10,
Throw(_) => 10,
SwapStack { .. } => 10,
CommonInst_GetThreadLocal | CommonInst_SetThreadLocal(_) => 10,
CommonInst_Pin(_) | CommonInst_Unpin(_) => 10,
// others
Move(_) => 0,
PrintHex(_) => 10,
PrintHex(_) => 10,
SetRetval(_) => 10,
ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner),
ExnInstruction { ref inner, .. } => estimate_insts_for_ir(&inner),
_ => unimplemented!(),
}
}
// Copyright 2017 The Australian National University
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
......@@ -26,18 +26,18 @@ use std::fs::File;
use std::collections::HashMap;
/// should emit Mu IR dot graph?
pub const EMIT_MUIR : bool = true;
pub const EMIT_MUIR: bool = true;
/// should emit machien code dot graph?
pub const EMIT_MC_DOT : bool = true;
pub const EMIT_MC_DOT: bool = true;
pub struct CodeEmission {
name: &'static str
name: &'static str,
}
impl CodeEmission {
pub fn new() -> CodeEmission {
CodeEmission {
name: "Code Emission"
name: "Code Emission",
}
}
}
......@@ -66,7 +66,7 @@ impl CompilerPass for CodeEmission {
pub fn create_emit_directory(vm: &VM) {
use std::fs;
match fs::create_dir(&vm.vm_options.flag_aot_emit_dir) {
Ok(_) => {},
Ok(_) => {}
Err(_) => {}
}
}
......@@ -78,8 +78,14 @@ fn create_emit_file(name: String, vm: &VM) -> File {
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
Err(why) => {
panic!(
"couldn't create emit file {}: {}",
file_path.to_str().unwrap(),
why
)
}
Ok(file) => file,
}
}
......@@ -92,8 +98,14 @@ pub fn emit_mu_types(suffix: &str, vm: &VM) {
file_path.push(&vm.vm_options.flag_aot_emit_dir);
file_path.push("___types".to_string() + suffix + ".muty");
let mut file = match File::create(file_path.as_path()) {
Err(why) => panic!("couldn't create mu types file {}: {}", file_path.to_str().unwrap(), why),
Ok(file) => file
Err(why) => {
panic!(
"couldn't create mu types file {}: {}",
file_path.to_str().unwrap(),
why
)
}
Ok(file) => file,
};
{
......@@ -107,12 +119,16 @@ pub fn emit_mu_types(suffix: &str, vm: &VM) {
if ty.is_struct() {
write!(file, "{}", ty).unwrap();
let struct_ty = struct_map.get(&ty.get_struct_hybrid_tag().unwrap()).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();
} else if ty.is_hybrid() {
write!(file, "{}", ty).unwrap();
let hybrid_ty = hybrid_map.get(&ty.get_struct_hybrid_tag().unwrap()).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();
} else {
......@@ -144,7 +160,7 @@ fn emit_mc_dot(func: &MuFunctionVersion, vm: &VM) {
let blocks = mc.get_all_blocks();
type DotID = usize;
let name_id_map : HashMap<MuName, DotID> = {
let name_id_map: HashMap<MuName, DotID> = {
let mut ret = HashMap::new();
let mut index = 0;
......@@ -159,7 +175,12 @@ fn emit_mc_dot(func: &MuFunctionVersion, vm: &VM) {
for block_name in blocks.iter() {
// BB [label = "
write!(file, "{} [label = \"{}:\\l\\l", id(block_name.clone()), block_name).unwrap();
write!(
file,
"{} [label = \"{}:\\l\\l",
id(block_name.clone()),
block_name
).unwrap();
for inst in mc.get_block_range(&block_name).unwrap() {
file.write_all(&mc.emit_inst(inst)).unwrap();
......@@ -173,8 +194,10 @@ fn emit_mc_dot(func: &MuFunctionVersion, vm: &VM) {
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) {
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());
......
// Copyright 2017 The Australian National University
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
......
This diff is collapsed.
// Copyright 2017 The Australian National University
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
......@@ -21,7 +21,7 @@ use compiler::backend;
use std::any::Any;
pub struct PeepholeOptimization {
name: &'static str
name: &'static str,
}
impl CompilerPass for PeepholeOptimization {
......@@ -38,7 +38,8 @@ impl CompilerPass for PeepholeOptimization {
let mut cf = compiled_funcs.get(&func.id()).unwrap().write().unwrap();
for i in 0..cf.mc().number_of_insts() {
// if two sides of a move instruction are the same, it is redundant, and can be eliminated
// if two sides of a move instruction are the same,
// it is redundant, and can be eliminated
self.remove_redundant_move(i, &mut cf);
// if a branch jumps a label that contains another jump, such as
......@@ -66,45 +67,49 @@ impl CompilerPass for PeepholeOptimization {
impl PeepholeOptimization {
pub fn new() -> PeepholeOptimization {
PeepholeOptimization {
name: "Peephole Optimization"
name: "Peephole Optimization",
}
}
fn remove_redundant_move(&mut self, inst: usize, cf: &mut CompiledFunction) {
// if this instruction is a move, and move from register to register (no memory operands)
if cf.mc().is_move(inst) && !cf.mc().is_using_mem_op(inst) {
cf.mc().trace_inst(inst);
// get source reg/temp ID
let src : MuID = {
let src: MuID = {
let uses = cf.mc().get_inst_reg_uses(inst);
if uses.len() == 0 {
// moving immediate to register, its not redundant
return;
}
}
uses[0]
};
// get dest reg/temp ID
let dst : MuID = cf.mc().get_inst_reg_defines(inst)[0];
let dst: MuID = cf.mc().get_inst_reg_defines(inst)[0];
// turning temp into machine reg
let src_machine_reg : MuID = {
let src_machine_reg: MuID = {
match cf.temps.get(&src) {
Some(reg) => *reg,
None => src
None => src,
}
};
let dst_machine_reg : MuID = {
let dst_machine_reg: MuID = {
match cf.temps.get(&dst) {
Some(reg) => *reg,
None => dst
None => dst,
}
};
// check if two registers are aliased
if backend::is_aliased(src_machine_reg, dst_machine_reg) {
info!("move between {} and {} is redundant! removed", src_machine_reg, dst_machine_reg);
info!(
"move between {} and {} is redundant! removed",
src_machine_reg,
dst_machine_reg
);
// redundant, remove this move
cf.mc_mut().set_inst_nop(inst);
} else {
......@@ -149,7 +154,7 @@ impl PeepholeOptimization {
// the instruction that we may rewrite
let orig_inst = inst;
// the destination we will rewrite the instruction to branch to
let final_dest : Option<MuName> = {
let final_dest: Option<MuName> = {
let mut cur_inst = inst;
let mut last_dest = None;
loop {
......@@ -158,8 +163,13 @@ impl PeepholeOptimization {
Some(ref dest) => {
// get the block for destination
let first_inst = mc.get_block_range(dest).unwrap().start;
debug_assert!(mc.is_label(first_inst).is_none(), "expect start inst {} of \
block {} is a inst instead of label", first_inst, dest);
debug_assert!(
mc.is_label(first_inst).is_none(),
"expect start inst {} of \
block {} is a inst instead of label",
first_inst,
dest
);
trace!("examining first inst {} of block {}", first_inst, dest);
......@@ -170,10 +180,10 @@ impl PeepholeOptimization {
cur_inst = first_inst;
last_dest = Some(dest2.clone());
}
None => break
None => break,
}
}
None => break
None => break,
}
}
last_dest
......@@ -184,13 +194,23 @@ impl PeepholeOptimization {
let start = mc.get_block_range(&dest).unwrap().start;
match mc.get_next_inst(start) {
Some(i) => i,
None => panic!("we are jumping to a block {}\
that does not have instructions?", dest)
None => {
panic!(
"we are jumping to a block {}\
that does not have instructions?",
dest
)
}
}
};
info!("inst {} chain jumps to {}, rewrite as branching to {} (successor: {})",
orig_inst, dest, dest, first_inst);
info!(
"inst {} chain jumps to {}, rewrite as branching to {} (successor: {})",
orig_inst,
dest,
dest,
first_inst
);
mc.replace_branch_dest(inst, &dest, first_inst);
}
}
......