This commit is contained in:
static
2025-06-18 03:06:34 +00:00
parent 58102acee3
commit 0fea4027ad

View File

@@ -249,7 +249,7 @@ impl InferenceGraph {
if !analysis.has_memcpy_in_prologue { if !analysis.has_memcpy_in_prologue {
for (aid, dtype) in code.blocks[&code.bid_init].phinodes.iter().enumerate() { for (aid, dtype) in code.blocks[&code.bid_init].phinodes.iter().enumerate() {
let rid = ir::RegisterId::arg(code.bid_init, aid); let rid = ir::RegisterId::arg(code.bid_init, aid);
if analysis.is_temporary2(&rid, &lives) { if analysis.is_temporary2(&rid, &lives, true) {
if is_integer(dtype) { if is_integer(dtype) {
let (_, asm_reg) = vertices.get_mut(&rid).unwrap(); let (_, asm_reg) = vertices.get_mut(&rid).unwrap();
*asm_reg = asm::Register::arg( *asm_reg = asm::Register::arg(
@@ -269,7 +269,7 @@ impl InferenceGraph {
for (bid, iid, _, reg) in &analysis.calls { for (bid, iid, _, reg) in &analysis.calls {
let rid = ir::RegisterId::temp(*bid, *iid); let rid = ir::RegisterId::temp(*bid, *iid);
if analysis.is_temporary2(&rid, &lives) { if analysis.is_temporary2(&rid, &lives, true) {
if let Some(reg) = reg { if let Some(reg) = reg {
let (_, asm_reg) = vertices.get_mut(&rid).unwrap(); let (_, asm_reg) = vertices.get_mut(&rid).unwrap();
*asm_reg = *reg; *asm_reg = *reg;
@@ -307,6 +307,7 @@ impl InferenceGraph {
reg, reg,
asm::Register::Saved(asm::RegisterType::Integer, _) asm::Register::Saved(asm::RegisterType::Integer, _)
| asm::Register::Arg(asm::RegisterType::Integer, _) | asm::Register::Arg(asm::RegisterType::Integer, _)
| asm::Register::Temp(asm::RegisterType::Integer, _)
) )
{ {
return Some(*reg); return Some(*reg);
@@ -316,6 +317,7 @@ impl InferenceGraph {
reg, reg,
asm::Register::Saved(asm::RegisterType::FloatingPoint, _) asm::Register::Saved(asm::RegisterType::FloatingPoint, _)
| asm::Register::Arg(asm::RegisterType::FloatingPoint, _) | asm::Register::Arg(asm::RegisterType::FloatingPoint, _)
| asm::Register::Temp(asm::RegisterType::FloatingPoint, _)
) )
{ {
return Some(*reg); return Some(*reg);
@@ -324,6 +326,19 @@ impl InferenceGraph {
}) })
.collect::<HashSet<_>>(); .collect::<HashSet<_>>();
if is_integer(dtype) { if is_integer(dtype) {
let smallest_temp_reg = smallest_missing_integer(
&neighbor_registers
.iter()
.filter_map(|reg| {
if let asm::Register::Temp(_, i) = reg {
Some(*i)
} else {
None
}
})
.collect(),
3,
); // t0~2는 못 씀
let smallest_arg_reg = smallest_missing_integer( let smallest_arg_reg = smallest_missing_integer(
&neighbor_registers &neighbor_registers
.iter() .iter()
@@ -350,7 +365,15 @@ impl InferenceGraph {
.collect(), .collect(),
1, 1,
); // s0는 못 씀 ); // s0는 못 씀
if smallest_arg_reg <= 7 && analysis.is_temporary2(&rid, &lives) { if smallest_temp_reg <= 6 && analysis.is_temporary2(&rid, &lives, false) {
let _unused = vertices.insert(
rid,
(
dtype.clone(),
asm::Register::temp(asm::RegisterType::Integer, smallest_temp_reg),
),
);
} else if smallest_arg_reg <= 7 && analysis.is_temporary2(&rid, &lives, true) {
let _unused = vertices.insert( let _unused = vertices.insert(
rid, rid,
( (
@@ -370,6 +393,19 @@ impl InferenceGraph {
// Spilling // Spilling
} }
} else if is_float(dtype) { } else if is_float(dtype) {
let smallest_temp_reg = smallest_missing_integer(
&neighbor_registers
.iter()
.filter_map(|reg| {
if let asm::Register::Temp(_, i) = reg {
Some(*i)
} else {
None
}
})
.collect(),
2,
); // ft0~1은 못 씀
let smallest_arg_reg = smallest_missing_integer( let smallest_arg_reg = smallest_missing_integer(
&neighbor_registers &neighbor_registers
.iter() .iter()
@@ -396,7 +432,18 @@ impl InferenceGraph {
.collect(), .collect(),
0, 0,
); );
if smallest_arg_reg <= 7 && analysis.is_temporary2(&rid, &lives) { if smallest_temp_reg <= 11 && analysis.is_temporary2(&rid, &lives, false) {
let _unused = vertices.insert(
rid,
(
dtype.clone(),
asm::Register::temp(
asm::RegisterType::FloatingPoint,
smallest_temp_reg,
),
),
);
} else if smallest_arg_reg <= 7 && analysis.is_temporary2(&rid, &lives, true) {
let _unused = vertices.insert( let _unused = vertices.insert(
rid, rid,
( (
@@ -493,6 +540,7 @@ impl Analysis {
&self, &self,
reg: &ir::RegisterId, reg: &ir::RegisterId,
lives: &HashMap<ir::RegisterId, HashSet<ir::RegisterId>>, lives: &HashMap<ir::RegisterId, HashSet<ir::RegisterId>>,
is_a_reg: bool,
) -> bool { ) -> bool {
for (call_bid, call_iid, call_args, _) in &self.calls { for (call_bid, call_iid, call_args, _) in &self.calls {
let lives_before = lives let lives_before = lives
@@ -501,7 +549,8 @@ impl Analysis {
let lives_after = lives let lives_after = lives
.get(&ir::RegisterId::temp(*call_bid, call_iid + 1)) .get(&ir::RegisterId::temp(*call_bid, call_iid + 1))
.unwrap(); .unwrap();
if lives_before.contains(reg) && (call_args.contains(reg) || lives_after.contains(reg)) if lives_before.contains(reg)
&& ((is_a_reg && call_args.contains(reg)) || lives_after.contains(reg))
{ {
return false; return false;
} }
@@ -920,14 +969,14 @@ impl Asmgen {
packing_size += field_size; packing_size += field_size;
} else { } else {
self.translate_addi( self.translate_addi(
asm::Register::T5, asm::Register::T2,
asm::Register::S0, asm::Register::S0,
stack_offset, stack_offset,
&mut insts, &mut insts,
); );
insts.push(asm::Instruction::SType { insts.push(asm::Instruction::SType {
instr: asm::SType::SD, instr: asm::SType::SD,
rs1: asm::Register::T5, rs1: asm::Register::T2,
rs2: asm::Register::arg( rs2: asm::Register::arg(
asm::RegisterType::Integer, asm::RegisterType::Integer,
num_int_args, num_int_args,
@@ -941,14 +990,14 @@ impl Asmgen {
} else if is_float(field_dtype) { } else if is_float(field_dtype) {
if is_packing { if is_packing {
self.translate_addi( self.translate_addi(
asm::Register::T5, asm::Register::T2,
asm::Register::S0, asm::Register::S0,
stack_offset, stack_offset,
&mut insts, &mut insts,
); );
insts.push(asm::Instruction::SType { insts.push(asm::Instruction::SType {
instr: asm::SType::SD, instr: asm::SType::SD,
rs1: asm::Register::T5, rs1: asm::Register::T2,
rs2: asm::Register::arg( rs2: asm::Register::arg(
asm::RegisterType::Integer, asm::RegisterType::Integer,
num_int_args, num_int_args,
@@ -960,14 +1009,14 @@ impl Asmgen {
} }
self.translate_addi( self.translate_addi(
asm::Register::T5, asm::Register::T2,
asm::Register::S0, asm::Register::S0,
stack_offset, stack_offset,
&mut insts, &mut insts,
); );
insts.push(asm::Instruction::SType { insts.push(asm::Instruction::SType {
instr: asm::SType::store(field_dtype.deref().clone()), instr: asm::SType::store(field_dtype.deref().clone()),
rs1: asm::Register::T5, rs1: asm::Register::T2,
rs2: asm::Register::arg( rs2: asm::Register::arg(
asm::RegisterType::FloatingPoint, asm::RegisterType::FloatingPoint,
num_float_args, num_float_args,
@@ -982,14 +1031,14 @@ impl Asmgen {
if is_packing { if is_packing {
self.translate_addi( self.translate_addi(
asm::Register::T5, asm::Register::T2,
asm::Register::S0, asm::Register::S0,
stack_offset, stack_offset,
&mut insts, &mut insts,
); );
insts.push(asm::Instruction::SType { insts.push(asm::Instruction::SType {
instr: asm::SType::SD, instr: asm::SType::SD,
rs1: asm::Register::T5, rs1: asm::Register::T2,
rs2: asm::Register::arg(asm::RegisterType::Integer, num_int_args), rs2: asm::Register::arg(asm::RegisterType::Integer, num_int_args),
imm: asm::Immediate::Value(packing_start_offset as u64), imm: asm::Immediate::Value(packing_start_offset as u64),
}); });
@@ -1908,7 +1957,7 @@ impl Asmgen {
ir::Operand::Register { rid, .. } => match rid { ir::Operand::Register { rid, .. } => match rid {
ir::RegisterId::Temp { bid, iid } => { ir::RegisterId::Temp { bid, iid } => {
self.translate_addi( self.translate_addi(
asm::Register::T5, asm::Register::T2,
asm::Register::S0, asm::Register::S0,
context.stack_offsets[rid], context.stack_offsets[rid],
&mut context.insts, &mut context.insts,
@@ -1952,7 +2001,7 @@ impl Asmgen {
asm::RegisterType::Integer, asm::RegisterType::Integer,
num_int_args, num_int_args,
), ),
rs1: asm::Register::T5, rs1: asm::Register::T2,
imm: asm::Immediate::Value( imm: asm::Immediate::Value(
packing_start_offset as u64, packing_start_offset as u64,
), ),
@@ -1970,7 +2019,7 @@ impl Asmgen {
asm::RegisterType::Integer, asm::RegisterType::Integer,
num_int_args, num_int_args,
), ),
rs1: asm::Register::T5, rs1: asm::Register::T2,
imm: asm::Immediate::Value( imm: asm::Immediate::Value(
packing_start_offset as u64, packing_start_offset as u64,
), ),
@@ -1985,7 +2034,7 @@ impl Asmgen {
asm::RegisterType::FloatingPoint, asm::RegisterType::FloatingPoint,
num_float_args, num_float_args,
), ),
rs1: asm::Register::T5, rs1: asm::Register::T2,
imm: asm::Immediate::Value(packing_start_offset as u64), imm: asm::Immediate::Value(packing_start_offset as u64),
}); });
num_float_args += 1; num_float_args += 1;
@@ -2001,7 +2050,7 @@ impl Asmgen {
asm::RegisterType::Integer, asm::RegisterType::Integer,
num_int_args, num_int_args,
), ),
rs1: asm::Register::T5, rs1: asm::Register::T2,
imm: asm::Immediate::Value(packing_start_offset as u64), imm: asm::Immediate::Value(packing_start_offset as u64),
}); });
num_int_args += 1; num_int_args += 1;
@@ -2115,14 +2164,14 @@ impl Asmgen {
.unwrap(); .unwrap();
if is_integer(field_dtype) { if is_integer(field_dtype) {
self.translate_addi( self.translate_addi(
asm::Register::T5, asm::Register::T2,
asm::Register::S0, asm::Register::S0,
context.stack_offsets[&rid], context.stack_offsets[&rid],
&mut context.insts, &mut context.insts,
); );
context.insts.push(asm::Instruction::SType { context.insts.push(asm::Instruction::SType {
instr: asm::SType::store(field_dtype.deref().clone()), instr: asm::SType::store(field_dtype.deref().clone()),
rs1: asm::Register::T5, rs1: asm::Register::T2,
rs2: asm::Register::arg( rs2: asm::Register::arg(
asm::RegisterType::Integer, asm::RegisterType::Integer,
num_int_fields, num_int_fields,
@@ -2132,14 +2181,14 @@ impl Asmgen {
num_int_fields += 1; num_int_fields += 1;
} else if is_float(field_dtype) { } else if is_float(field_dtype) {
self.translate_addi( self.translate_addi(
asm::Register::T5, asm::Register::T2,
asm::Register::S0, asm::Register::S0,
context.stack_offsets[&rid], context.stack_offsets[&rid],
&mut context.insts, &mut context.insts,
); );
context.insts.push(asm::Instruction::SType { context.insts.push(asm::Instruction::SType {
instr: asm::SType::store(field_dtype.deref().clone()), instr: asm::SType::store(field_dtype.deref().clone()),
rs1: asm::Register::T5, rs1: asm::Register::T2,
rs2: asm::Register::arg( rs2: asm::Register::arg(
asm::RegisterType::FloatingPoint, asm::RegisterType::FloatingPoint,
num_float_fields, num_float_fields,
@@ -2623,7 +2672,7 @@ impl Asmgen {
}, },
ir::Operand::Register { rid, .. } => match rid { ir::Operand::Register { rid, .. } => match rid {
ir::RegisterId::Temp { bid, iid } => self.translate_addi( ir::RegisterId::Temp { bid, iid } => self.translate_addi(
asm::Register::T5, asm::Register::T2,
asm::Register::S0, asm::Register::S0,
context.stack_offsets[rid], context.stack_offsets[rid],
&mut context.insts, &mut context.insts,
@@ -2648,7 +2697,7 @@ impl Asmgen {
asm::RegisterType::Integer, asm::RegisterType::Integer,
num_int_fields, num_int_fields,
), ),
rs1: asm::Register::T5, rs1: asm::Register::T2,
imm: asm::Immediate::Value(offset as u64), imm: asm::Immediate::Value(offset as u64),
}); });
num_int_fields += 1; num_int_fields += 1;
@@ -2659,7 +2708,7 @@ impl Asmgen {
asm::RegisterType::FloatingPoint, asm::RegisterType::FloatingPoint,
num_float_fields, num_float_fields,
), ),
rs1: asm::Register::T5, rs1: asm::Register::T2,
imm: asm::Immediate::Value(offset as u64), imm: asm::Immediate::Value(offset as u64),
}); });
num_float_fields += 1; num_float_fields += 1;
@@ -2717,13 +2766,13 @@ impl Asmgen {
32 => context 32 => context
.insts .insts
.push(asm::Instruction::Pseudo(asm::Pseudo::Li { .push(asm::Instruction::Pseudo(asm::Pseudo::Li {
rd: asm::Register::T4, rd: asm::Register::T2,
imm: (*value as f32).to_bits() as u64, imm: (*value as f32).to_bits() as u64,
})), })),
64 => context 64 => context
.insts .insts
.push(asm::Instruction::Pseudo(asm::Pseudo::Li { .push(asm::Instruction::Pseudo(asm::Pseudo::Li {
rd: asm::Register::T4, rd: asm::Register::T2,
imm: value.to_bits(), imm: value.to_bits(),
})), })),
_ => unreachable!(), _ => unreachable!(),
@@ -2731,7 +2780,7 @@ impl Asmgen {
context.insts.push(asm::Instruction::RType { context.insts.push(asm::Instruction::RType {
instr: asm::RType::fmv_int_to_float(ir::Dtype::float(width)), instr: asm::RType::fmv_int_to_float(ir::Dtype::float(width)),
rd, rd,
rs1: asm::Register::T4, rs1: asm::Register::T2,
rs2: None, rs2: None,
}); });
} }
@@ -3101,14 +3150,14 @@ impl Asmgen {
}); });
} else { } else {
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li { insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
rd: asm::Register::T3, rd: asm::Register::T2,
imm, imm,
})); }));
insts.push(asm::Instruction::RType { insts.push(asm::Instruction::RType {
instr: asm::RType::add(ir::Dtype::int(64)), instr: asm::RType::add(ir::Dtype::int(64)),
rd, rd,
rs1, rs1,
rs2: Some(asm::Register::T3), rs2: Some(asm::Register::T2),
}); });
} }
} }
@@ -3131,18 +3180,18 @@ impl Asmgen {
}); });
} else { } else {
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li { insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
rd: asm::Register::T3, rd: asm::Register::T2,
imm, imm,
})); }));
insts.push(asm::Instruction::RType { insts.push(asm::Instruction::RType {
instr: asm::RType::add(ir::Dtype::int(64)), instr: asm::RType::add(ir::Dtype::int(64)),
rd: asm::Register::T3, rd: asm::Register::T2,
rs1, rs1,
rs2: Some(asm::Register::T3), rs2: Some(asm::Register::T2),
}); });
insts.push(asm::Instruction::SType { insts.push(asm::Instruction::SType {
instr, instr,
rs1: asm::Register::T3, rs1: asm::Register::T2,
rs2, rs2,
imm: asm::Immediate::Value(0), imm: asm::Immediate::Value(0),
}); });
@@ -3167,19 +3216,19 @@ impl Asmgen {
}); });
} else { } else {
insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li { insts.push(asm::Instruction::Pseudo(asm::Pseudo::Li {
rd: asm::Register::T3, rd: asm::Register::T2,
imm, imm,
})); }));
insts.push(asm::Instruction::RType { insts.push(asm::Instruction::RType {
instr: asm::RType::add(ir::Dtype::int(64)), instr: asm::RType::add(ir::Dtype::int(64)),
rd: asm::Register::T3, rd: asm::Register::T2,
rs1, rs1,
rs2: Some(asm::Register::T3), rs2: Some(asm::Register::T2),
}); });
insts.push(asm::Instruction::IType { insts.push(asm::Instruction::IType {
instr, instr,
rd, rd,
rs1: asm::Register::T3, rs1: asm::Register::T2,
imm: asm::Immediate::Value(0), imm: asm::Immediate::Value(0),
}); });
} }
@@ -3204,8 +3253,8 @@ fn get_rhs_register(dtype: &ir::Dtype) -> asm::Register {
fn get_res_register(dtype: &ir::Dtype) -> asm::Register { fn get_res_register(dtype: &ir::Dtype) -> asm::Register {
match dtype { match dtype {
ir::Dtype::Int { .. } | ir::Dtype::Pointer { .. } => asm::Register::T2, ir::Dtype::Int { .. } | ir::Dtype::Pointer { .. } => asm::Register::T1,
ir::Dtype::Float { .. } => asm::Register::FT2, ir::Dtype::Float { .. } => asm::Register::FT1,
_ => todo!(), _ => todo!(),
} }
} }