Skip to content

Commit 69d618f

Browse files
committed
Use binary search to find IR block offsets
1 parent c22adcf commit 69d618f

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

Core/MIPS/IR/IRJit.cpp

+33-2
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ void IRJit::RunLoopUntil(u64 globalticks) {
252252
while (mips->downcount >= 0) {
253253
u32 inst = Memory::ReadUnchecked_U32(mips->pc);
254254
u32 opcode = inst & 0xFF000000;
255-
u32 offset = inst & 0x00FFFFFF;
256255
if (opcode == MIPS_EMUHACK_OPCODE) {
256+
u32 offset = inst & 0x00FFFFFF; // Alternatively, inst - opcode
257257
mips->pc = IRInterpret(mips, blocks_.GetArenaPtr() + offset);
258258
// Note: this will "jump to zero" on a badly constructed block missing exits.
259259
if (!Memory::IsValid4AlignedAddress(mips->pc)) {
@@ -297,13 +297,43 @@ void IRBlockCache::Clear() {
297297
arena_.shrink_to_fit();
298298
}
299299

300+
IRBlockCache::IRBlockCache() {
301+
// For whatever reason, this makes things go slower?? Probably just a CPU cache alignment fluke.
302+
// arena_.reserve(1024 * 1024 * 2);
303+
}
304+
300305
int IRBlockCache::GetBlockNumFromOffset(int offset) const {
306+
// Block offsets are always in rising order (we don't go back and replace them when invalidated). So we can binary search.
307+
int low = 0;
308+
int high = (int)blocks_.size() - 1;
309+
int found = -1;
310+
while (low <= high) {
311+
int mid = low + (high - low) / 2;
312+
const int blockOffset = blocks_[mid].GetInstructionOffset();
313+
if (blockOffset == offset) {
314+
found = mid;
315+
break;
316+
}
317+
if (blockOffset < offset) {
318+
low = mid + 1;
319+
} else {
320+
high = mid - 1;
321+
}
322+
}
323+
324+
#ifndef _DEBUG
325+
// Then, in debug builds, cross check the result.
326+
return found;
327+
#else
301328
// TODO: Optimize if we need to call this often.
302329
for (int i = 0; i < (int)blocks_.size(); i++) {
303330
if (blocks_[i].GetInstructionOffset() == offset) {
331+
_dbg_assert_(i == found);
304332
return i;
305333
}
306334
}
335+
#endif
336+
_dbg_assert_(found == -1);
307337
return -1;
308338
}
309339

@@ -377,12 +407,13 @@ int IRBlockCache::FindByCookie(int cookie) {
377407
if (blocks_[0].GetTargetOffset() < 0)
378408
return GetBlockNumFromOffset(cookie);
379409

410+
// TODO: Now that we are using offsets in pure IR mode too, we can probably unify
411+
// the two paradigms. Or actually no, we still need two offsets..
380412
for (int i = 0; i < GetNumBlocks(); ++i) {
381413
int offset = blocks_[i].GetTargetOffset();
382414
if (offset == cookie)
383415
return i;
384416
}
385-
386417
return -1;
387418
}
388419

Core/MIPS/IR/IRJit.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class IRBlock {
100100

101101
class IRBlockCache : public JitBlockCacheDebugInterface {
102102
public:
103-
IRBlockCache() {}
103+
IRBlockCache();
104104
void Clear();
105105
std::vector<int> FindInvalidatedBlockNumbers(u32 address, u32 length);
106106
void FinalizeBlock(int blockNum, bool preload = false);

GPU/Common/VertexDecoderCommon.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ void VertexDecoder::Step_Color5551() const
520520
u8 *c = decoded_ + decFmt.c0off;
521521
u16 cdata = *(const u16_le *)(ptr_ + coloff);
522522
gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (cdata >> 15) != 0;
523+
523524
c[0] = Convert5To8(cdata & 0x1f);
524525
c[1] = Convert5To8((cdata >> 5) & 0x1f);
525526
c[2] = Convert5To8((cdata >> 10) & 0x1f);
@@ -558,7 +559,7 @@ void VertexDecoder::Step_Color565Morph() const
558559
c[i] = clamp_u8((int)col[i]);
559560
}
560561
c[3] = 255;
561-
// Always full alpha.
562+
// Always full alpha. (Is this true??)
562563
}
563564

564565
void VertexDecoder::Step_Color5551Morph() const

0 commit comments

Comments
 (0)