[dynarmic] Remove redundant constant pool ops

Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie
2026-10-08 12:16:29 +00:00
parent 10bcd2d849
commit 51f2e2bfb9
2 changed files with 20 additions and 40 deletions
@@ -7,34 +7,27 @@
*/ */
#include <cstring> #include <cstring>
#include <cassert>
#include "common/assert.h"
#include "dynarmic/backend/x64/block_of_code.h" #include "dynarmic/backend/x64/block_of_code.h"
#include "dynarmic/backend/x64/constant_pool.h" #include "dynarmic/backend/x64/constant_pool.h"
namespace Dynarmic::Backend::X64 { namespace Dynarmic::Backend::X64 {
ConstantPool::ConstantPool(BlockOfCode& code, size_t size) ConstantPool::ConstantPool(BlockOfCode& code, size_t size) noexcept {
: insertion_point(0) auto const align_size = 64; //always align to cacheline
{ code.EnsureMemoryCommitted(2 * align_size + size);
code.EnsureMemoryCommitted(align_size + size);
code.int3();
code.align(align_size); code.align(align_size);
pool = std::span<ConstantT>(reinterpret_cast<ConstantT*>(code.AllocateFromCodeSpace(size)), size / align_size); pool = std::span<u128>(static_cast<u128*>(code.AllocateFromCodeSpace(size)), size / sizeof(u128));
} }
Xbyak::Address ConstantPool::GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lower, u64 upper) { Xbyak::Address ConstantPool::GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lo, u64 hi) noexcept {
const auto constant = ConstantT(lower, upper); // offset grows iff new constant is added
auto it = constant_info.find(constant); auto const key = std::make_pair(lo, hi);
if (it == constant_info.end()) { auto const val = u32(constant_info.size());
ASSERT(insertion_point < pool.size()); auto const [it, _] = constant_info.insert({key, val});
ConstantT& target_constant = pool[insertion_point]; // if it != constant_info.end(): assume(pool[it->second] == c);
target_constant = constant; pool[it->second] = u128{lo, hi};
it = constant_info.insert({constant, &target_constant}).first; return frame[code.rip + std::addressof(pool[it->second])];
++insertion_point;
}
return frame[code.rip + it->second];
} }
} // namespace Dynarmic::Backend::X64 } // namespace Dynarmic::Backend::X64
@@ -12,6 +12,7 @@
#include <cstddef> #include <cstddef>
#include <span> #include <span>
#include <utility> #include <utility>
#include <boost/functional/hash.hpp>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/container/unordered_map.h" #include "common/container/unordered_map.h"
@@ -21,31 +22,17 @@ namespace Dynarmic::Backend::X64 {
class BlockOfCode; class BlockOfCode;
/// ConstantPool allocates a block of memory from BlockOfCode. /// @brief ConstantPool allocates a block of memory from BlockOfCode.
/// It places constants into this block of memory, returning the address /// It places constants into this block of memory, returning the address
/// of the memory location where the constant is placed. If the constant /// of the memory location where the constant is placed. If the constant
/// already exists, its memory location is reused. /// already exists, its memory location is reused.
class ConstantPool final { class ConstantPool final {
public: public:
ConstantPool(BlockOfCode& code, size_t size); ConstantPool(BlockOfCode& code, size_t size) noexcept;
Xbyak::Address GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lower, u64 upper = 0) noexcept;
Xbyak::Address GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lower, u64 upper = 0); // key = identity hash, value = offset from pool.data()
::Common::unordered_map<std::pair<u64, u64>, u32, boost::hash<std::pair<u64, u64>>> constant_info;
private: std::span<u128> pool;
static constexpr size_t align_size = 16; // bytes
using ConstantT = std::pair<u64, u64>;
static_assert(sizeof(ConstantT) == align_size);
struct ConstantHash {
std::size_t operator()(const ConstantT& constant) const noexcept {
return constant.first ^ std::rotl<u64>(constant.second, 1);
}
};
::Common::unordered_map<ConstantT, void*, ConstantHash> constant_info;
std::span<ConstantT> pool;
std::size_t insertion_point;
}; };
} // namespace Dynarmic::Backend::X64 } // namespace Dynarmic::Backend::X64