mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-12 23:48:58 +01:00
Merge pull request #9666 from leoetlino/jit-block-hashtable
Jit: Optimize block link queries by using hash tables
This commit is contained in:
commit
ac679eb24d
@ -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
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user