Skip to content

Commit 211b909

Browse files
committed
Fix wrong exit blocks
1 parent 2d5c0a7 commit 211b909

File tree

5 files changed

+38
-22
lines changed

5 files changed

+38
-22
lines changed

src/bitset.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ impl<const SIZE: usize> Bitset<SIZE> {
4242
pub const fn is_empty(&self) -> bool {
4343
self.len() == 0
4444
}
45+
46+
pub const fn clear(&mut self) {
47+
self.0 = [0; SIZE];
48+
}
4549
}
4650

4751
impl<const SIZE: usize> Default for Bitset<SIZE> {

src/jit/assembler/block_asm.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,17 @@ impl<'a> BlockAsm<'a> {
664664
}
665665
}
666666

667+
fn resolve_actual_block_count(already_processed: &mut NoHashSet<usize>, basic_blocks: &mut [BasicBlock], block_i: usize, count: &mut usize) {
668+
*count += 1;
669+
already_processed.insert(block_i);
670+
for i in 0..basic_blocks[block_i].exit_blocks.len() {
671+
let exit_i = basic_blocks[block_i].exit_blocks[i];
672+
if !already_processed.contains(&exit_i) {
673+
Self::resolve_actual_block_count(already_processed, basic_blocks, exit_i, count);
674+
}
675+
}
676+
}
677+
667678
fn resolve_df_ordering(
668679
already_processed: &mut Bitset<{ 1024 / 32 }>,
669680
completed: &mut Bitset<{ 1024 / 32 }>,
@@ -697,7 +708,7 @@ impl<'a> BlockAsm<'a> {
697708
*completed += block_i;
698709
}
699710

700-
fn assemble_basic_blocks(&mut self, block_start_pc: u32, thumb: bool) -> (Vec<BasicBlock>, Vec<usize>) {
711+
fn assemble_basic_blocks(&mut self, block_start_pc: u32, thumb: bool) -> (Vec<BasicBlock>, Vec<usize>, NoHashSet<usize>) {
701712
for i in 0..self.buf.insts.len() {
702713
self.insts_link.insert_end(i);
703714
}
@@ -737,7 +748,7 @@ impl<'a> BlockAsm<'a> {
737748
}
738749
last_label = None;
739750
}
740-
BlockInstKind::Call { has_return: false, .. } | BlockInstKind::Epilogue { .. } => {
751+
BlockInstKind::Call { has_return: false, .. } | BlockInstKind::CallCommon { has_return: false, .. } | BlockInstKind::Epilogue { .. } => {
741752
basic_blocks.push(BasicBlock::new(self, basic_block_start, current_node));
742753
basic_block_start = BlockInstList::deref(current_node).next;
743754
if let Some(last_label) = last_label {
@@ -773,16 +784,13 @@ impl<'a> BlockAsm<'a> {
773784
}
774785
}
775786
// Don't add exit when last command in basic block is a breakout
776-
BlockInstKind::Call { has_return: false, .. } | BlockInstKind::Epilogue { .. } => {
777-
if i + 1 < basic_blocks_len {
778-
basic_block.exit_blocks.push(i + 1);
779-
}
780-
}
781-
_ => {
782-
if i + 1 < basic_blocks_len {
787+
BlockInstKind::Call { has_return: false, .. } | BlockInstKind::CallCommon { has_return: false, .. } | BlockInstKind::Epilogue { .. } => {
788+
if cond != Cond::AL && i + 1 < basic_blocks_len {
783789
basic_block.exit_blocks.push(i + 1);
784790
}
785791
}
792+
_ if i + 1 < basic_blocks_len => basic_block.exit_blocks.push(i + 1),
793+
_ => {}
786794
}
787795
}
788796

@@ -828,11 +836,15 @@ impl<'a> BlockAsm<'a> {
828836
basic_block.remove_dead_code(self);
829837
}
830838

839+
let mut reachable_blocks = NoHashSet::default();
840+
let mut actual_block_count = 0;
841+
Self::resolve_actual_block_count(&mut reachable_blocks, &mut basic_blocks, 0, &mut actual_block_count);
842+
831843
let mut df_already_processed = Bitset::<{ 1024 / 32 }>::new();
832844
let mut df_completed = Bitset::<{ 1024 / 32 }>::new();
833-
let mut df_ordering = vec![0; basic_blocks_len];
845+
let mut df_ordering = vec![0; actual_block_count];
834846
let mut df_ordering_start = 0;
835-
let mut df_ordering_end = basic_blocks_len - 1;
847+
let mut df_ordering_end = actual_block_count - 1;
836848
Self::resolve_df_ordering(
837849
&mut df_already_processed,
838850
&mut df_completed,
@@ -843,7 +855,7 @@ impl<'a> BlockAsm<'a> {
843855
&mut df_ordering_end,
844856
);
845857

846-
(basic_blocks, df_ordering)
858+
(basic_blocks, df_ordering, reachable_blocks)
847859
}
848860

849861
fn assemble_intervals(basic_blocks: &[BasicBlock], ordering: &[usize]) -> NoHashMap<u16, (usize, usize)> {
@@ -872,7 +884,7 @@ impl<'a> BlockAsm<'a> {
872884
}
873885

874886
pub fn emit_opcodes(&mut self, block_start_pc: u32, thumb: bool) -> usize {
875-
let (mut basic_blocks, basic_blocks_order) = self.assemble_basic_blocks(block_start_pc, thumb);
887+
let (mut basic_blocks, basic_blocks_order, reachable_blocks) = self.assemble_basic_blocks(block_start_pc, thumb);
876888

877889
if IS_DEBUG && unsafe { BLOCK_LOG } {
878890
for (i, basic_block) in basic_blocks.iter().enumerate() {
@@ -919,7 +931,7 @@ impl<'a> BlockAsm<'a> {
919931
}
920932

921933
for (i, basic_block) in basic_blocks.iter_mut().enumerate() {
922-
if unlikely(i != 0 && basic_block.enter_blocks.is_empty()) {
934+
if unlikely(i != 0 && !reachable_blocks.contains(&i)) {
923935
continue;
924936
}
925937
self.buf.reg_allocator.init_inputs(*basic_block.get_required_inputs());
@@ -944,7 +956,7 @@ impl<'a> BlockAsm<'a> {
944956
for (i, basic_block) in basic_blocks.iter().enumerate() {
945957
let opcodes_len = self.buf.opcodes.len();
946958
self.buf.block_opcode_offsets.push(opcodes_len);
947-
if unlikely(i != 0 && basic_block.enter_blocks.is_empty()) {
959+
if unlikely(i != 0 && !reachable_blocks.contains(&i)) {
948960
continue;
949961
}
950962
let opcodes = basic_block.emit_opcodes(self, opcodes_len, used_host_regs);

src/jit/emitter/emit.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
7070
block_asm.load_u32(guest_pc_reg, block_asm.thread_regs_addr_reg, Reg::PC as u32 * 4);
7171
self.emit_branch_return_stack_common(block_asm, guest_pc_reg);
7272
block_asm.free_reg(guest_pc_reg);
73+
} else {
74+
self.emit_branch_out_metadata(block_asm);
75+
block_asm.epilogue();
7376
}
74-
75-
self.emit_branch_out_metadata(block_asm);
76-
block_asm.epilogue();
7777
}
7878

7979
block_asm.end_cond_block();

src/jit/emitter/thumb/emit_thumb.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
9090
block_asm.load_u32(guest_pc_reg, block_asm.thread_regs_addr_reg, Reg::PC as u32 * 4);
9191
self.emit_branch_return_stack_common(block_asm, guest_pc_reg);
9292
block_asm.free_reg(guest_pc_reg);
93+
} else {
94+
self.emit_branch_out_metadata(block_asm);
95+
block_asm.epilogue();
9396
}
94-
95-
self.emit_branch_out_metadata(block_asm);
96-
block_asm.epilogue();
9797
}
9898
}
9999
}

src/jit/jit_asm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ fn emit_code_block_internal<const CPU: CpuType, const THUMB: bool>(asm: &mut Jit
186186
}
187187

188188
let jit_entry = {
189-
// unsafe { BLOCK_LOG = guest_pc == 0x206d6d8 };
189+
// unsafe { BLOCK_LOG = guest_pc == 0x20027ac };
190190

191191
let mut block_asm = asm.new_block_asm(false);
192192

0 commit comments

Comments
 (0)