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