[dynarmic] reuse IR::Block memory instead of creating new block each time
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
866881d0e3
commit
710bbe0b0d
|
|
@ -25,6 +25,7 @@
|
|||
#include "dynarmic/backend/x64/devirtualize.h"
|
||||
#include "dynarmic/backend/x64/jitstate_info.h"
|
||||
#include "dynarmic/common/atomic.h"
|
||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||
#include "dynarmic/frontend/A32/translate/a32_translate.h"
|
||||
#include "dynarmic/interface/A32/a32.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
|
|
@ -63,12 +64,14 @@ static Optimization::PolyfillOptions GenPolyfillOptions(const BlockOfCode& code)
|
|||
}
|
||||
|
||||
struct Jit::Impl {
|
||||
Impl(Jit* jit, A32::UserConfig conf)
|
||||
: block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf))
|
||||
, emitter(block_of_code, conf, jit)
|
||||
, polyfill_options(GenPolyfillOptions(block_of_code))
|
||||
, conf(std::move(conf))
|
||||
, jit_interface(jit) {}
|
||||
Impl(Jit* jit, A32::UserConfig conf) noexcept
|
||||
: ir_block{LocationDescriptor(0, PSR(0), FPSCR(0), false)}
|
||||
, conf(std::move(conf))
|
||||
, block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf))
|
||||
, emitter(block_of_code, conf, jit)
|
||||
, polyfill_options(GenPolyfillOptions(block_of_code))
|
||||
, jit_interface(jit)
|
||||
{}
|
||||
|
||||
~Impl() = default;
|
||||
|
||||
|
|
@ -212,7 +215,8 @@ private:
|
|||
}
|
||||
block_of_code.EnsureMemoryCommitted(MINIMUM_REMAINING_CODESIZE);
|
||||
|
||||
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
ir_block.Reset(descriptor);
|
||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
Optimization::Optimize(ir_block, conf, polyfill_options);
|
||||
return emitter.Emit(ir_block);
|
||||
}
|
||||
|
|
@ -239,13 +243,12 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
IR::Block ir_block;
|
||||
const A32::UserConfig conf;
|
||||
A32JitState jit_state;
|
||||
BlockOfCode block_of_code;
|
||||
A32EmitX64 emitter;
|
||||
Optimization::PolyfillOptions polyfill_options;
|
||||
|
||||
const A32::UserConfig conf;
|
||||
|
||||
Jit* jit_interface;
|
||||
|
||||
// Requests made during execution to invalidate the cache are queued up here.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/fp/fpcr.h"
|
||||
#include "dynarmic/common/llvm_disassemble.h"
|
||||
#include <bit>
|
||||
#include <mcl/scope_exit.hpp>
|
||||
|
|
@ -61,10 +62,12 @@ static Optimization::PolyfillOptions GenPolyfillOptions(const BlockOfCode& code)
|
|||
struct Jit::Impl final {
|
||||
public:
|
||||
Impl(Jit* jit, UserConfig conf)
|
||||
: conf(conf)
|
||||
, block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf))
|
||||
, emitter(block_of_code, conf, jit)
|
||||
, polyfill_options(GenPolyfillOptions(block_of_code)) {
|
||||
: ir_block{LocationDescriptor(0, FP::FPCR(0), false)}
|
||||
, conf(conf)
|
||||
, block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf))
|
||||
, emitter(block_of_code, conf, jit)
|
||||
, polyfill_options(GenPolyfillOptions(block_of_code))
|
||||
{
|
||||
ASSERT(conf.page_table_address_space_bits >= 12 && conf.page_table_address_space_bits <= 64);
|
||||
}
|
||||
|
||||
|
|
@ -268,8 +271,8 @@ private:
|
|||
|
||||
// JIT Compile
|
||||
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
|
||||
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{current_location}, get_code,
|
||||
{conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||
ir_block.Reset(current_location);
|
||||
A64::Translate(ir_block, A64::LocationDescriptor{current_location}, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||
Optimization::Optimize(ir_block, conf, polyfill_options);
|
||||
return emitter.Emit(ir_block).entrypoint;
|
||||
}
|
||||
|
|
@ -296,14 +299,13 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
bool is_executing = false;
|
||||
|
||||
IR::Block ir_block;
|
||||
const UserConfig conf;
|
||||
A64JitState jit_state;
|
||||
BlockOfCode block_of_code;
|
||||
A64EmitX64 emitter;
|
||||
Optimization::PolyfillOptions polyfill_options;
|
||||
|
||||
bool is_executing = false;
|
||||
bool invalidate_entire_cache = false;
|
||||
boost::icl::interval_set<u64> invalid_cache_ranges;
|
||||
std::mutex invalidation_mutex;
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
IR::Block TranslateArm(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
IR::Block TranslateThumb(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
|
||||
IR::Block Translate(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(descriptor, tcb, options);
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(block, descriptor, tcb, options);
|
||||
}
|
||||
|
||||
bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ struct TranslationOptions {
|
|||
* @param options Configures how certain instructions are translated.
|
||||
* @return A translated basic block in the intermediate representation.
|
||||
*/
|
||||
IR::Block Translate(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
|
||||
/**
|
||||
* This function translates a single provided instruction into our intermediate representation.
|
||||
|
|
|
|||
|
|
@ -22,12 +22,9 @@
|
|||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
IR::Block TranslateArm(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
const bool single_step = descriptor.SingleStepping();
|
||||
|
||||
IR::Block block{descriptor};
|
||||
TranslatorVisitor visitor{block, descriptor, options};
|
||||
|
||||
bool should_continue = true;
|
||||
do {
|
||||
const u32 arm_pc = visitor.ir.current_location.PC();
|
||||
|
|
@ -76,12 +73,8 @@ IR::Block TranslateArm(LocationDescriptor descriptor, TranslateCallbacks* tcb, c
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(block.HasTerminal() && "Terminal has not been set");
|
||||
|
||||
block.SetEndLocation(visitor.ir.current_location);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 arm_instruction) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "dynarmic/frontend/A32/translate/translate_callbacks.h"
|
||||
#include "dynarmic/frontend/imm.h"
|
||||
#include "dynarmic/interface/A32/config.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
namespace {
|
||||
|
|
@ -103,12 +104,9 @@ inline bool MaybeVFPOrASIMDInstruction(u32 thumb_instruction) noexcept {
|
|||
|
||||
} // namespace
|
||||
|
||||
IR::Block TranslateThumb(LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
const bool single_step = descriptor.SingleStepping();
|
||||
|
||||
IR::Block block{descriptor};
|
||||
TranslatorVisitor visitor{block, descriptor, options};
|
||||
|
||||
bool should_continue = true;
|
||||
do {
|
||||
const u32 arm_pc = visitor.ir.current_location.PC();
|
||||
|
|
@ -175,12 +173,8 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, TranslateCallbacks* tcb,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(block.HasTerminal() && "Terminal has not been set");
|
||||
|
||||
block.SetEndLocation(visitor.ir.current_location);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descriptor, u32 thumb_instruction) {
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@
|
|||
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options) {
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options) {
|
||||
const bool single_step = descriptor.SingleStepping();
|
||||
|
||||
IR::Block block{descriptor};
|
||||
TranslatorVisitor visitor{block, descriptor, std::move(options)};
|
||||
|
||||
bool should_continue = true;
|
||||
|
|
@ -43,12 +41,8 @@ IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory
|
|||
if (single_step && should_continue) {
|
||||
visitor.ir.SetTerm(IR::Term::LinkBlock{*visitor.ir.current_location});
|
||||
}
|
||||
|
||||
ASSERT(block.HasTerminal() && "Terminal has not been set");
|
||||
|
||||
block.SetEndLocation(*visitor.ir.current_location);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction) {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ struct TranslationOptions {
|
|||
* @param options Configures how certain instructions are translated.
|
||||
* @return A translated basic block in the intermediate representation.
|
||||
*/
|
||||
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options);
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options);
|
||||
|
||||
/**
|
||||
* This function translates a single provided instruction into our intermediate representation.
|
||||
|
|
|
|||
|
|
@ -140,6 +140,18 @@ public:
|
|||
return cycle_count;
|
||||
}
|
||||
|
||||
inline void Reset(LocationDescriptor location_) noexcept {
|
||||
inlined_inst.clear();
|
||||
pooled_inst.clear();
|
||||
cond_failed.reset();
|
||||
location = location_;
|
||||
terminal = Term::Invalid{};
|
||||
cond_failed_cycle_count = 0;
|
||||
cycle_count = 0;
|
||||
instruction_list_type tmp{};
|
||||
instructions.swap(tmp);
|
||||
}
|
||||
|
||||
/// "Hot cache" for small blocks so we don't call global allocator
|
||||
boost::container::static_vector<Inst, 30> inlined_inst;
|
||||
/// List of instructions in this block.
|
||||
|
|
|
|||
Loading…
Reference in New Issue