mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-15 15:08:52 +00:00
HW8 (6)
This commit is contained in:
@@ -234,7 +234,7 @@ impl InferenceGraph {
|
|||||||
*num_of_edges.entry(*rid1).or_insert(0) += 1;
|
*num_of_edges.entry(*rid1).or_insert(0) += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (mut num_int_args, mut num_float_args) =
|
let (mut num_int_args, mut num_float_args, primitive_arg_reg_index) =
|
||||||
get_number_of_register_arguments(&signature.ret, &signature.params, structs);
|
get_number_of_register_arguments(&signature.ret, &signature.params, structs);
|
||||||
let mut has_call = false;
|
let mut has_call = false;
|
||||||
let mut is_a0_return_pointer = false;
|
let mut is_a0_return_pointer = false;
|
||||||
@@ -286,13 +286,32 @@ impl InferenceGraph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !has_call {
|
||||||
|
for (aid, dtype) in code.blocks[&code.bid_init].phinodes.iter().enumerate() {
|
||||||
|
let rid = ir::RegisterId::arg(code.bid_init, aid);
|
||||||
|
if is_integer(dtype) {
|
||||||
|
let (_, asm_reg) = vertices.get_mut(&rid).unwrap();
|
||||||
|
*asm_reg = asm::Register::arg(
|
||||||
|
asm::RegisterType::Integer,
|
||||||
|
primitive_arg_reg_index[&aid] as usize,
|
||||||
|
);
|
||||||
|
} else if is_float(dtype) {
|
||||||
|
let (_, asm_reg) = vertices.get_mut(&rid).unwrap();
|
||||||
|
*asm_reg = asm::Register::arg(
|
||||||
|
asm::RegisterType::FloatingPoint,
|
||||||
|
primitive_arg_reg_index[&aid] as usize,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut vertices_order = vertices
|
let mut vertices_order = vertices
|
||||||
.keys()
|
.keys()
|
||||||
.map(|rid| (*rid, num_of_edges.get(rid).cloned().unwrap_or_default()))
|
.map(|rid| (*rid, num_of_edges.get(rid).cloned().unwrap_or_default()))
|
||||||
.sorted_by(|(_, v1), (_, v2)| v2.cmp(v1));
|
.sorted_by(|(_, v1), (_, v2)| v2.cmp(v1));
|
||||||
|
|
||||||
for (rid, count) in vertices_order {
|
for (rid, count) in vertices_order {
|
||||||
if count == 0 {
|
if count == 0 || vertices[&rid].1 != asm::Register::Zero {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,7 +565,7 @@ impl Asmgen {
|
|||||||
if let Some(definition) = definition {
|
if let Some(definition) = definition {
|
||||||
let graph = InferenceGraph::new(definition, signature, structs);
|
let graph = InferenceGraph::new(definition, signature, structs);
|
||||||
|
|
||||||
// println!("asdf: {:?}", graph.vertices);
|
// println!("{name} asdf: {:?}", graph.vertices);
|
||||||
|
|
||||||
let mut context =
|
let mut context =
|
||||||
self.translate_prologue(signature, definition, structs, graph);
|
self.translate_prologue(signature, definition, structs, graph);
|
||||||
@@ -758,7 +777,9 @@ impl Asmgen {
|
|||||||
let rs = asm::Register::arg(asm::RegisterType::Integer, num_int_args);
|
let rs = asm::Register::arg(asm::RegisterType::Integer, num_int_args);
|
||||||
num_int_args += 1;
|
num_int_args += 1;
|
||||||
if let Some(rd) = rd {
|
if let Some(rd) = rd {
|
||||||
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Mv { rd, rs }));
|
if rd != rs {
|
||||||
|
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Mv { rd, rs }));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.translate_store(
|
self.translate_store(
|
||||||
asm::SType::store(dtype.clone()),
|
asm::SType::store(dtype.clone()),
|
||||||
@@ -772,11 +793,13 @@ impl Asmgen {
|
|||||||
let rs = asm::Register::arg(asm::RegisterType::FloatingPoint, num_float_args);
|
let rs = asm::Register::arg(asm::RegisterType::FloatingPoint, num_float_args);
|
||||||
num_float_args += 1;
|
num_float_args += 1;
|
||||||
if let Some(rd) = rd {
|
if let Some(rd) = rd {
|
||||||
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Fmv {
|
if rd != rs {
|
||||||
data_size: asm::DataSize::try_from(dtype.clone()).unwrap(),
|
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Fmv {
|
||||||
rd,
|
data_size: asm::DataSize::try_from(dtype.clone()).unwrap(),
|
||||||
rs,
|
rd,
|
||||||
}));
|
rs,
|
||||||
|
}));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.translate_store(
|
self.translate_store(
|
||||||
asm::SType::store(dtype.clone()),
|
asm::SType::store(dtype.clone()),
|
||||||
@@ -2265,48 +2288,76 @@ impl Asmgen {
|
|||||||
ir::Instruction::GetElementPtr { ptr, offset, .. } => {
|
ir::Instruction::GetElementPtr { ptr, offset, .. } => {
|
||||||
let ptr_dtype = ptr.dtype();
|
let ptr_dtype = ptr.dtype();
|
||||||
let offset_dtype = offset.dtype();
|
let offset_dtype = offset.dtype();
|
||||||
let rs2 = self.translate_load_operand(
|
let rd = rd.unwrap_or(get_res_register(&ptr_dtype));
|
||||||
offset,
|
|
||||||
get_rhs_register(&offset_dtype),
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
match ptr {
|
match ptr {
|
||||||
ir::Operand::Constant(ir::Constant::GlobalVariable {
|
ir::Operand::Constant(ir::Constant::GlobalVariable {
|
||||||
name: ptr_name,
|
name: ptr_name,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let rd = rd.unwrap_or(get_res_register(&ptr_dtype));
|
|
||||||
context
|
context
|
||||||
.insts
|
.insts
|
||||||
.push(asm::Instruction::Pseudo(asm::Pseudo::La {
|
.push(asm::Instruction::Pseudo(asm::Pseudo::La {
|
||||||
rd: asm::Register::T0,
|
rd: asm::Register::T0,
|
||||||
symbol: asm::Label(ptr_name.clone()),
|
symbol: asm::Label(ptr_name.clone()),
|
||||||
}));
|
}));
|
||||||
context.insts.push(asm::Instruction::RType {
|
let mut imm_mode = false;
|
||||||
instr: asm::RType::add(ptr_dtype.clone()),
|
if let Some(ir::Constant::Int { value, .. }) = offset.get_constant() {
|
||||||
rd,
|
if (-2048..=2047).contains(&(*value as i128)) {
|
||||||
rs1: asm::Register::T0,
|
context.insts.push(asm::Instruction::IType {
|
||||||
rs2: Some(rs2),
|
instr: asm::IType::ADDI,
|
||||||
});
|
rd,
|
||||||
|
rs1: asm::Register::T0,
|
||||||
|
imm: asm::Immediate::Value(*value as u64),
|
||||||
|
});
|
||||||
|
imm_mode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !imm_mode {
|
||||||
|
let rs2 = self.translate_load_operand(
|
||||||
|
offset,
|
||||||
|
get_rhs_register(&offset_dtype),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
context.insts.push(asm::Instruction::RType {
|
||||||
|
instr: asm::RType::add(ptr_dtype.clone()),
|
||||||
|
rd,
|
||||||
|
rs1: asm::Register::T0,
|
||||||
|
rs2: Some(rs2),
|
||||||
|
});
|
||||||
|
}
|
||||||
if is_spilled {
|
if is_spilled {
|
||||||
self.translate_store_result(&rid, ptr_dtype, rd, context);
|
self.translate_store_result(&rid, ptr_dtype, rd, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir::Operand::Register { rid: ptr_rid, .. } => match ptr_rid {
|
ir::Operand::Register { rid: ptr_rid, .. } => match ptr_rid {
|
||||||
ir::RegisterId::Local { aid } => {
|
ir::RegisterId::Local { aid } => {
|
||||||
let rd = rd.unwrap_or(get_res_register(&ptr_dtype));
|
if let Some(ir::Constant::Int { value, .. }) = offset.get_constant()
|
||||||
self.translate_addi(
|
{
|
||||||
rd,
|
self.translate_addi(
|
||||||
asm::Register::S0,
|
rd,
|
||||||
context.stack_offsets[ptr_rid],
|
asm::Register::S0,
|
||||||
&mut context.insts,
|
context.stack_offsets[ptr_rid] + (*value as u64),
|
||||||
);
|
&mut context.insts,
|
||||||
context.insts.push(asm::Instruction::RType {
|
);
|
||||||
instr: asm::RType::add(ptr_dtype.clone()),
|
} else {
|
||||||
rd,
|
let rs2 = self.translate_load_operand(
|
||||||
rs1: rd,
|
offset,
|
||||||
rs2: Some(rs2),
|
get_rhs_register(&offset_dtype),
|
||||||
});
|
context,
|
||||||
|
);
|
||||||
|
self.translate_addi(
|
||||||
|
rd,
|
||||||
|
asm::Register::S0,
|
||||||
|
context.stack_offsets[ptr_rid],
|
||||||
|
&mut context.insts,
|
||||||
|
);
|
||||||
|
context.insts.push(asm::Instruction::RType {
|
||||||
|
instr: asm::RType::add(ptr_dtype.clone()),
|
||||||
|
rd,
|
||||||
|
rs1: rd,
|
||||||
|
rs2: Some(rs2),
|
||||||
|
});
|
||||||
|
}
|
||||||
if is_spilled {
|
if is_spilled {
|
||||||
self.translate_store_result(&rid, ptr_dtype, rd, context);
|
self.translate_store_result(&rid, ptr_dtype, rd, context);
|
||||||
}
|
}
|
||||||
@@ -2317,13 +2368,32 @@ impl Asmgen {
|
|||||||
get_lhs_register(&ptr_dtype),
|
get_lhs_register(&ptr_dtype),
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
let rd = rd.unwrap_or(get_res_register(&ptr_dtype));
|
let mut imm_mode = false;
|
||||||
context.insts.push(asm::Instruction::RType {
|
if let Some(ir::Constant::Int { value, .. }) = offset.get_constant()
|
||||||
instr: asm::RType::add(ptr_dtype.clone()),
|
{
|
||||||
rd,
|
if (-2048..=2047).contains(&(*value as i128)) {
|
||||||
rs1,
|
context.insts.push(asm::Instruction::IType {
|
||||||
rs2: Some(rs2),
|
instr: asm::IType::ADDI,
|
||||||
});
|
rd,
|
||||||
|
rs1,
|
||||||
|
imm: asm::Immediate::Value(*value as u64),
|
||||||
|
});
|
||||||
|
imm_mode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !imm_mode {
|
||||||
|
let rs2 = self.translate_load_operand(
|
||||||
|
offset,
|
||||||
|
get_rhs_register(&offset_dtype),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
context.insts.push(asm::Instruction::RType {
|
||||||
|
instr: asm::RType::add(ptr_dtype.clone()),
|
||||||
|
rd,
|
||||||
|
rs1,
|
||||||
|
rs2: Some(rs2),
|
||||||
|
});
|
||||||
|
}
|
||||||
if is_spilled {
|
if is_spilled {
|
||||||
self.translate_store_result(&rid, ptr_dtype, rd, context);
|
self.translate_store_result(&rid, ptr_dtype, rd, context);
|
||||||
}
|
}
|
||||||
@@ -2632,13 +2702,29 @@ impl Asmgen {
|
|||||||
context: &Context,
|
context: &Context,
|
||||||
structs: &HashMap<String, Option<ir::Dtype>>,
|
structs: &HashMap<String, Option<ir::Dtype>>,
|
||||||
) -> Vec<asm::Instruction> {
|
) -> Vec<asm::Instruction> {
|
||||||
|
let bid = arg.bid;
|
||||||
|
let mut referenced_org_phinodes = HashSet::new();
|
||||||
|
for arg in &arg.args {
|
||||||
|
if let ir::Operand::Register {
|
||||||
|
rid: ir::RegisterId::Arg { bid: arg_bid, aid },
|
||||||
|
..
|
||||||
|
} = arg
|
||||||
|
{
|
||||||
|
if *arg_bid == bid {
|
||||||
|
let _ = referenced_org_phinodes.insert(aid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut phinode_stack_offsets = HashMap::new();
|
let mut phinode_stack_offsets = HashMap::new();
|
||||||
let mut phinode_stack_allocations = 0;
|
let mut phinode_stack_allocations = 0;
|
||||||
|
|
||||||
for (aid, arg) in arg.args.iter().enumerate() {
|
for (aid, arg) in arg.args.iter().enumerate() {
|
||||||
let _ = phinode_stack_offsets.insert(aid, phinode_stack_allocations);
|
if referenced_org_phinodes.contains(&aid) {
|
||||||
phinode_stack_allocations +=
|
let _ = phinode_stack_offsets.insert(aid, phinode_stack_allocations);
|
||||||
ceil_to_multiple_of_16(get_dtype_size(&arg.dtype(), structs));
|
phinode_stack_allocations +=
|
||||||
|
ceil_to_multiple_of_16(get_dtype_size(&arg.dtype(), structs));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut phinode_insts = Vec::new();
|
let mut phinode_insts = Vec::new();
|
||||||
@@ -2651,31 +2737,33 @@ impl Asmgen {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap Issue를 해결하기 위해 스택에 기존 phinode값 일괄 저장
|
// Swap Issue를 해결하기 위해 스택에 기존 phinode값 저장 (필요한 것만)
|
||||||
let bid = arg.bid;
|
let bid = arg.bid;
|
||||||
for (aid, arg) in arg.args.iter().enumerate() {
|
for (aid, arg) in arg.args.iter().enumerate() {
|
||||||
let rid = ir::RegisterId::arg(bid, aid);
|
if referenced_org_phinodes.contains(&aid) {
|
||||||
let arg_dtype = arg.dtype();
|
let rid = ir::RegisterId::arg(bid, aid);
|
||||||
let rs1 = if let Some(rs1) = context.inference_graph.get_register(&rid) {
|
let arg_dtype = arg.dtype();
|
||||||
rs1
|
let rs1 = if let Some(rs1) = context.inference_graph.get_register(&rid) {
|
||||||
} else {
|
rs1
|
||||||
let rs1 = get_lhs_register(&arg_dtype);
|
} else {
|
||||||
self.translate_load(
|
let rs1 = get_lhs_register(&arg_dtype);
|
||||||
asm::IType::load(arg_dtype.clone()),
|
self.translate_load(
|
||||||
|
asm::IType::load(arg_dtype.clone()),
|
||||||
|
rs1,
|
||||||
|
asm::Register::S0,
|
||||||
|
context.stack_offsets[&rid],
|
||||||
|
&mut phinode_insts,
|
||||||
|
);
|
||||||
|
rs1
|
||||||
|
};
|
||||||
|
self.translate_store(
|
||||||
|
asm::SType::store(arg_dtype),
|
||||||
|
asm::Register::Sp,
|
||||||
rs1,
|
rs1,
|
||||||
asm::Register::S0,
|
phinode_stack_offsets[&aid],
|
||||||
context.stack_offsets[&rid],
|
|
||||||
&mut phinode_insts,
|
&mut phinode_insts,
|
||||||
);
|
);
|
||||||
rs1
|
}
|
||||||
};
|
|
||||||
self.translate_store(
|
|
||||||
asm::SType::store(arg_dtype),
|
|
||||||
asm::Register::Sp,
|
|
||||||
rs1,
|
|
||||||
phinode_stack_offsets[&aid],
|
|
||||||
&mut phinode_insts,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (aid, arg) in arg.args.iter().enumerate() {
|
for (aid, arg) in arg.args.iter().enumerate() {
|
||||||
@@ -3069,20 +3157,23 @@ fn get_struct_dtype<'a>(
|
|||||||
|
|
||||||
fn get_number_of_register_arguments(
|
fn get_number_of_register_arguments(
|
||||||
return_type: &ir::Dtype,
|
return_type: &ir::Dtype,
|
||||||
params: &Vec<ir::Dtype>,
|
params: &[ir::Dtype],
|
||||||
structs: &HashMap<String, Option<ir::Dtype>>,
|
structs: &HashMap<String, Option<ir::Dtype>>,
|
||||||
) -> (i32, i32) {
|
) -> (i32, i32, HashMap<usize, i32>) {
|
||||||
let mut num_int_args = 0;
|
let mut num_int_args = 0;
|
||||||
let mut num_float_args = 0;
|
let mut num_float_args = 0;
|
||||||
|
let mut primitive_arg_reg_index = HashMap::new();
|
||||||
|
|
||||||
if is_struct(return_type, structs).is_some_and(|size| size > 16) {
|
if is_struct(return_type, structs).is_some_and(|size| size > 16) {
|
||||||
num_int_args += 1;
|
num_int_args += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for dtype in params {
|
for (i, dtype) in params.iter().enumerate() {
|
||||||
if is_integer(dtype) {
|
if is_integer(dtype) {
|
||||||
|
let _ = primitive_arg_reg_index.insert(i, num_int_args);
|
||||||
num_int_args += 1;
|
num_int_args += 1;
|
||||||
} else if is_float(dtype) {
|
} else if is_float(dtype) {
|
||||||
|
let _ = primitive_arg_reg_index.insert(i, num_float_args);
|
||||||
num_float_args += 1;
|
num_float_args += 1;
|
||||||
} else if let Some(size) = is_struct(dtype, structs) {
|
} else if let Some(size) = is_struct(dtype, structs) {
|
||||||
if size > 16 {
|
if size > 16 {
|
||||||
@@ -3137,5 +3228,5 @@ fn get_number_of_register_arguments(
|
|||||||
num_float_args = 1;
|
num_float_args = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
(num_int_args, num_float_args)
|
(num_int_args, num_float_args, primitive_arg_reg_index)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user