git subrepo pull --force deps/lightrec
[pcsx_rearmed.git] / deps / lightrec / lightrec.c
index 13434b4..1cf755b 100644 (file)
@@ -1559,6 +1559,7 @@ static void lightrec_reap_opcode_list(struct lightrec_state *state, void *data)
 int lightrec_compile_block(struct lightrec_cstate *cstate,
                           struct block *block)
 {
+       u32 was_dead[ARRAY_SIZE(cstate->targets) / 8];
        struct lightrec_state *state = cstate->state;
        struct lightrec_branch_target *target;
        bool fully_tagged = false;
@@ -1677,11 +1678,8 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
        /* Add compiled function to the LUT */
        lut_write(state, lut_offset(block->pc), block->function);
 
-       if (ENABLE_THREADED_COMPILER)
-               lightrec_reaper_continue(state->reaper);
-
        /* Detect old blocks that have been covered by the new one */
-       for (i = 0; i < cstate->nb_targets; i++) {
+       for (i = 0; ENABLE_THREADED_COMPILER && i < cstate->nb_targets; i++) {
                target = &cstate->targets[i];
 
                if (!target->offset)
@@ -1689,12 +1687,6 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
 
                offset = block->pc + target->offset * sizeof(u32);
 
-               /* Pause the reaper while we search for the block until we set
-                * the BLOCK_IS_DEAD flag, otherwise the block may be removed
-                * under our feet. */
-               if (ENABLE_THREADED_COMPILER)
-                       lightrec_reaper_pause(state->reaper);
-
                block2 = lightrec_find_block(state->block_cache, offset);
                if (block2) {
                        /* No need to check if block2 is compilable - it must
@@ -1703,17 +1695,24 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
                        /* Set the "block dead" flag to prevent the dynarec from
                         * recompiling this block */
                        old_flags = block_set_flags(block2, BLOCK_IS_DEAD);
+
+                       if (old_flags & BLOCK_IS_DEAD)
+                               was_dead[i / 32] |= BIT(i % 32);
+                       else
+                               was_dead[i / 32] &= ~BIT(i % 32);
                }
 
-               if (ENABLE_THREADED_COMPILER) {
-                       lightrec_reaper_continue(state->reaper);
+               /* If block2 was pending for compilation, cancel it.
+                * If it's being compiled right now, wait until it finishes. */
+               if (block2)
+                       lightrec_recompiler_remove(state->rec, block2);
+       }
 
-                       /* If block2 was pending for compilation, cancel it.
-                        * If it's being compiled right now, wait until it
-                        * finishes. */
-                       if (block2)
-                               lightrec_recompiler_remove(state->rec, block2);
-               }
+       for (i = 0; i < cstate->nb_targets; i++) {
+               target = &cstate->targets[i];
+
+               if (!target->offset)
+                       continue;
 
                /* We know from now on that block2 (if present) isn't going to
                 * be compiled. We can override the LUT entry with our new
@@ -1721,6 +1720,8 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
                offset = lut_offset(block->pc) + target->offset;
                lut_write(state, offset, jit_address(target->label));
 
+               offset = block->pc + target->offset * sizeof(u32);
+               block2 = lightrec_find_block(state->block_cache, offset);
                if (block2) {
                        pr_debug("Reap block 0x%08x as it's covered by block "
                                 "0x%08x\n", block2->pc, block->pc);
@@ -1729,7 +1730,7 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
                        if (!ENABLE_THREADED_COMPILER) {
                                lightrec_unregister_block(state->block_cache, block2);
                                lightrec_free_block(state, block2);
-                       } else if (!(old_flags & BLOCK_IS_DEAD)) {
+                       } else if (!(was_dead[i / 32] & BIT(i % 32))) {
                                lightrec_reaper_add(state->reaper,
                                                    lightrec_reap_block,
                                                    block2);
@@ -1737,6 +1738,9 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
                }
        }
 
+       if (ENABLE_THREADED_COMPILER)
+               lightrec_reaper_continue(state->reaper);
+
        if (ENABLE_DISASSEMBLER) {
                pr_debug("Compiling block at PC: 0x%08x\n", block->pc);
                jit_disassemble();