Merge pull request #9666 from leoetlino/jit-block-hashtable

Jit: Optimize block link queries by using hash tables
This commit is contained in:
JosJuice 2021-04-25 18:45:41 +02:00 committed by GitHub
commit ac679eb24d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 21 deletions

View File

@ -127,7 +127,7 @@ void JitBaseBlockCache::FinalizeBlock(JitBlock& block, bool block_link,
{ {
for (const auto& e : block.linkData) for (const auto& e : block.linkData)
{ {
links_to.emplace(e.exitAddress, &block); links_to[e.exitAddress].insert(&block);
} }
LinkBlock(block); LinkBlock(block);
@ -299,13 +299,14 @@ void JitBaseBlockCache::LinkBlockExits(JitBlock& block)
void JitBaseBlockCache::LinkBlock(JitBlock& block) void JitBaseBlockCache::LinkBlock(JitBlock& block)
{ {
LinkBlockExits(block); LinkBlockExits(block);
auto ppp = links_to.equal_range(block.effectiveAddress); const auto it = links_to.find(block.effectiveAddress);
if (it == links_to.end())
return;
for (auto iter = ppp.first; iter != ppp.second; ++iter) for (JitBlock* b2 : it->second)
{ {
JitBlock& b2 = *iter->second; if (block.msrBits == b2->msrBits)
if (block.msrBits == b2.msrBits) LinkBlockExits(*b2);
LinkBlockExits(b2);
} }
} }
@ -318,14 +319,15 @@ void JitBaseBlockCache::UnlinkBlock(const JitBlock& block)
} }
// Unlink all exits of other blocks which points to this block // Unlink all exits of other blocks which points to this block
auto ppp = links_to.equal_range(block.effectiveAddress); const auto it = links_to.find(block.effectiveAddress);
for (auto iter = ppp.first; iter != ppp.second; ++iter) if (it == links_to.end())
return;
for (JitBlock* sourceBlock : it->second)
{ {
JitBlock& sourceBlock = *iter->second; if (sourceBlock->msrBits != block.msrBits)
if (sourceBlock.msrBits != block.msrBits)
continue; continue;
for (auto& e : sourceBlock.linkData) for (auto& e : sourceBlock->linkData)
{ {
if (e.exitAddress == block.effectiveAddress) if (e.exitAddress == block.effectiveAddress)
{ {
@ -346,14 +348,12 @@ void JitBaseBlockCache::DestroyBlock(JitBlock& block)
// Delete linking addresses // Delete linking addresses
for (const auto& e : block.linkData) for (const auto& e : block.linkData)
{ {
auto it = links_to.equal_range(e.exitAddress); auto it = links_to.find(e.exitAddress);
while (it.first != it.second) if (it == links_to.end())
{ continue;
if (it.first->second == &block) it->second.erase(&block);
it.first = links_to.erase(it.first); if (it->second.empty())
else links_to.erase(it);
it.first++;
}
} }
// Raise an signal if we are going to call this block again // Raise an signal if we are going to call this block again

View File

@ -12,6 +12,8 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <type_traits> #include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -182,7 +184,7 @@ private:
// links_to hold all exit points of all valid blocks in a reverse way. // links_to hold all exit points of all valid blocks in a reverse way.
// It is used to query all blocks which links to an address. // It is used to query all blocks which links to an address.
std::multimap<u32, JitBlock*> links_to; // destination_PC -> number std::unordered_map<u32, std::unordered_set<JitBlock*>> links_to; // destination_PC -> number
// Map indexed by the physical address of the entry point. // Map indexed by the physical address of the entry point.
// This is used to query the block based on the current PC in a slow way. // This is used to query the block based on the current PC in a slow way.
@ -192,7 +194,7 @@ private:
// This is used for invalidation of memory regions. The range is grouped // This is used for invalidation of memory regions. The range is grouped
// in macro blocks of each 0x100 bytes. // in macro blocks of each 0x100 bytes.
static constexpr u32 BLOCK_RANGE_MAP_ELEMENTS = 0x100; static constexpr u32 BLOCK_RANGE_MAP_ELEMENTS = 0x100;
std::map<u32, std::set<JitBlock*>> block_range_map; std::map<u32, std::unordered_set<JitBlock*>> block_range_map;
// This bitsets shows which cachelines overlap with any blocks. // This bitsets shows which cachelines overlap with any blocks.
// It is used to provide a fast way to query if no icache invalidation is needed. // It is used to provide a fast way to query if no icache invalidation is needed.