Skip to content

Commit d3824ef

Browse files
committed
Simplify context loading
1 parent 2912b67 commit d3824ef

File tree

4 files changed

+32
-81
lines changed

4 files changed

+32
-81
lines changed

src/jit/assembler/basic_block.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -241,22 +241,17 @@ impl BasicBlock {
241241
}
242242
}
243243

244-
pub fn remove_dead_code(&mut self, asm: &BlockAsm) {
244+
pub fn remove_dead_code(&mut self, asm: &mut BlockAsm) {
245245
let mut current_node = self.insts_link.root;
246246
let mut i = 0;
247247
while !current_node.is_null() {
248248
let inst_i = BlockInstList::deref(current_node).value;
249-
let inst = &asm.buf.insts[inst_i];
249+
let inst = &mut asm.buf.insts[inst_i];
250250
if let BlockInstKind::RestoreReg { guest_reg, .. } = &inst.kind {
251251
if *guest_reg != Reg::CPSR {
252252
let (_, outputs) = inst.get_io();
253253
if (self.regs_live_ranges[i + 1] - outputs) == self.regs_live_ranges[i + 1] {
254-
let next_node = BlockInstList::deref(current_node).next;
255-
self.insts_link.remove_entry(current_node);
256-
current_node = next_node;
257-
self.regs_live_ranges.remove(i);
258-
self.used_regs.remove(i);
259-
continue;
254+
inst.skip = true;
260255
}
261256
}
262257
}
@@ -289,12 +284,15 @@ impl BasicBlock {
289284
let mut current_node = self.insts_link.root;
290285
while !current_node.is_null() {
291286
let inst_i = BlockInstList::deref(current_node).value;
292-
asm.buf.reg_allocator.inst_allocate(&mut asm.buf.insts[inst_i], &self.regs_live_ranges[i..], &self.used_regs[i..]);
293-
if !asm.buf.reg_allocator.pre_allocate_insts.is_empty() {
294-
for i in asm.buf.insts.len()..asm.buf.insts.len() + asm.buf.reg_allocator.pre_allocate_insts.len() {
295-
self.insts_link.insert_entry_begin(current_node, i);
287+
let inst = &mut asm.buf.insts[inst_i];
288+
if !inst.skip {
289+
asm.buf.reg_allocator.inst_allocate(inst, &self.regs_live_ranges[i..], &self.used_regs[i..]);
290+
if !asm.buf.reg_allocator.pre_allocate_insts.is_empty() {
291+
for i in asm.buf.insts.len()..asm.buf.insts.len() + asm.buf.reg_allocator.pre_allocate_insts.len() {
292+
self.insts_link.insert_entry_begin(current_node, i);
293+
}
294+
asm.buf.insts.extend_from_slice(&asm.buf.reg_allocator.pre_allocate_insts);
296295
}
297-
asm.buf.insts.extend_from_slice(&asm.buf.reg_allocator.pre_allocate_insts);
298296
}
299297
i += 1;
300298
current_node = BlockInstList::deref(current_node).next;
@@ -323,6 +321,9 @@ impl BasicBlock {
323321
let mut inst_opcodes = Vec::new();
324322
for entry in self.insts_link.iter() {
325323
let inst = &mut asm.buf.insts[entry.value];
324+
if inst.skip {
325+
continue;
326+
}
326327

327328
if IS_DEBUG && unsafe { BLOCK_LOG } {
328329
match &inst.kind {

src/jit/assembler/block_asm.rs

Lines changed: 11 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::jit::{Cond, MemoryAmount, ShiftType};
1212
use crate::utils::{NoHashMap, NoHashSet};
1313
use crate::IS_DEBUG;
1414
use std::intrinsics::unlikely;
15-
use std::{ptr, slice};
15+
use std::slice;
1616

1717
pub static mut BLOCK_LOG: bool = false;
1818

@@ -58,7 +58,6 @@ pub struct BlockAsm<'a> {
5858

5959
cond_block_end_label_stack: Vec<(BlockLabel, Cond, usize)>,
6060

61-
guest_reg_init_offset: Option<usize>,
6261
is_common_fun: bool,
6362
host_sp_ptr: *mut usize,
6463
block_start: usize,
@@ -94,7 +93,6 @@ impl<'a> BlockAsm<'a> {
9493

9594
cond_block_end_label_stack: Vec::new(),
9695

97-
guest_reg_init_offset: None,
9896
is_common_fun,
9997
host_sp_ptr,
10098
block_start: 0,
@@ -117,7 +115,9 @@ impl<'a> BlockAsm<'a> {
117115

118116
if !is_common_fun {
119117
instance.mov(thread_regs_addr_reg, guest_regs_ptr as u32);
120-
instance.guest_reg_init_offset = Some(instance.buf.insts.len() - 1);
118+
for guest_reg in RegReserve::gp() + Reg::SP + Reg::LR {
119+
instance.restore_reg(guest_reg);
120+
}
121121
instance.restore_reg(Reg::CPSR);
122122
}
123123

@@ -921,72 +921,14 @@ impl<'a> BlockAsm<'a> {
921921
basic_block.remove_dead_code(self);
922922
}
923923

924-
if let Some(guest_regs_init_offset) = self.guest_reg_init_offset {
925-
let required_guest_regs = basic_blocks[0].get_required_inputs().get_guests();
926-
if !required_guest_regs.is_empty() {
927-
let mut basic_block_i = 0;
928-
let mut inst_i = 0;
929-
let mut inst_entry = ptr::null_mut();
930-
931-
'basic_blocks_loop: for (i, basic_block) in basic_blocks.iter_mut().enumerate() {
932-
if !reachable_blocks.contains(&i) {
933-
continue;
934-
}
935-
936-
for (j, entry) in basic_block.insts_link.iter().enumerate() {
937-
if entry.value == guest_regs_init_offset {
938-
basic_block_i = i;
939-
inst_i = j;
940-
inst_entry = entry as *const _ as *mut _;
941-
break 'basic_blocks_loop;
942-
}
943-
}
944-
}
945-
946-
let basic_block = &mut basic_blocks[basic_block_i];
947-
for i in 0..=inst_i {
948-
basic_block.regs_live_ranges[i].remove_guests(required_guest_regs);
949-
}
950-
let enter_blocks = unsafe { slice::from_raw_parts(basic_block.enter_blocks.as_ptr(), basic_block.enter_blocks.len()) };
951-
Self::remove_guest_input_regs(&mut basic_blocks, required_guest_regs, enter_blocks);
952-
let basic_block = &mut basic_blocks[basic_block_i];
953-
954-
let mut previous_guest_reg = None;
955-
for (j, guest_reg) in required_guest_regs.into_iter().enumerate() {
956-
inst_entry = basic_block.insts_link.insert_entry_end(inst_entry, self.buf.insts.len());
957-
self.buf.insts.push(
958-
BlockInstKind::RestoreReg {
959-
guest_reg,
960-
reg_mapped: guest_reg.into(),
961-
thread_regs_addr_reg: self.thread_regs_addr_reg,
962-
tmp_guest_cpsr_reg: self.tmp_guest_cpsr_reg,
963-
}
964-
.into(),
965-
);
966-
let inst_index = inst_i + j + 1;
967-
968-
let (inputs, outputs) = self.buf.insts.last().unwrap().get_io();
969-
basic_block.used_regs.insert(inst_index, inputs + outputs);
970-
971-
let mut previous_regs_live_range = basic_block.regs_live_ranges[inst_index - 1];
972-
if let Some(previous_guest_reg) = previous_guest_reg {
973-
previous_regs_live_range += BlockReg::from(previous_guest_reg);
974-
}
975-
previous_regs_live_range += inputs;
976-
basic_block.regs_live_ranges.insert(inst_index, previous_regs_live_range);
977-
978-
previous_guest_reg = Some(guest_reg);
979-
}
980-
}
981-
}
982-
983924
(basic_blocks, reachable_blocks)
984925
}
985926

986927
pub fn emit_opcodes(&mut self, block_start_pc: u32, thumb: bool) -> usize {
987928
let (mut basic_blocks, reachable_blocks) = self.assemble_basic_blocks(block_start_pc, thumb);
988929

989-
if !basic_blocks[0].get_required_inputs().get_guests().is_empty() {
930+
if IS_DEBUG && !basic_blocks[0].get_required_inputs().get_guests().is_empty() {
931+
println!("inputs as requirement {:?}", basic_blocks[0].get_required_inputs().get_guests());
990932
unsafe { BLOCK_LOG = true };
991933
}
992934

@@ -1090,7 +1032,11 @@ impl<'a> BlockAsm<'a> {
10901032
let branch_to = self.buf.block_opcode_offsets[block_index as usize];
10911033
branch_to as i32 - branch_placeholder as i32
10921034
};
1093-
self.buf.opcodes[branch_placeholder] = if encoding.has_return() { B::bl } else { B::b }(diff - 2, Cond::from(u8::from(encoding.cond())));
1035+
if diff == 1 && !encoding.has_return() {
1036+
self.buf.opcodes[branch_placeholder] = AluShiftImm::mov_al(Reg::R0, Reg::R0);
1037+
} else {
1038+
self.buf.opcodes[branch_placeholder] = if encoding.has_return() { B::bl } else { B::b }(diff - 2, Cond::from(u8::from(encoding.cond())));
1039+
}
10941040
}
10951041

10961042
&self.buf.opcodes

src/jit/assembler/block_inst.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pub struct BlockInst {
7878
pub cond: Cond,
7979
pub kind: BlockInstKind,
8080
io_cache: RefCell<Option<(BlockRegSet, BlockRegSet)>>,
81+
pub skip: bool,
8182
}
8283

8384
impl BlockInst {
@@ -86,6 +87,7 @@ impl BlockInst {
8687
cond,
8788
kind,
8889
io_cache: RefCell::new(None),
90+
skip: false,
8991
}
9092
}
9193

@@ -129,7 +131,11 @@ impl From<BlockInstKind> for BlockInst {
129131

130132
impl Debug for BlockInst {
131133
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
132-
write!(f, "{:?} {:?}", self.cond, self.kind)
134+
if self.skip {
135+
write!(f, "SKIPPED: {:?} {:?}", self.cond, self.kind)
136+
} else {
137+
write!(f, "{:?} {:?}", self.cond, self.kind)
138+
}
133139
}
134140
}
135141

src/jit/emitter/emit_transfer.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,6 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
216216
}
217217
block_asm.restore_reg(Reg::CPSR);
218218

219-
block_asm.branch(continue_label, Cond::AL);
220-
221219
block_asm.label(continue_label);
222220

223221
block_asm.free_reg(fast_read_addr_masked_reg);

0 commit comments

Comments
 (0)