Add optimization flags to disable specific optimizations

This commit is contained in:
MerryMage 2020-06-28 21:39:26 +01:00
parent 3eed024caf
commit 4ba1f8b9e7
13 changed files with 160 additions and 96 deletions

View file

@ -7,6 +7,7 @@ add_library(dynarmic
../include/dynarmic/A64/a64.h
../include/dynarmic/A64/config.h
../include/dynarmic/exclusive_monitor.h
../include/dynarmic/optimization_flags.h
common/assert.cpp
common/assert.h
common/bit_util.h

View file

@ -185,7 +185,7 @@ void A32EmitX64::EmitCondPrelude(const A32EmitContext& ctx) {
}
void A32EmitX64::ClearFastDispatchTable() {
if (conf.enable_fast_dispatch) {
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
fast_dispatch_table.fill({});
}
}
@ -272,7 +272,7 @@ void A32EmitX64::GenTerminalHandlers() {
code.and_(eax, u32(A32JitState::RSBPtrMask));
code.mov(dword[r15 + offsetof(A32JitState, rsb_ptr)], eax);
code.cmp(rbx, qword[r15 + offsetof(A32JitState, rsb_location_descriptors) + rax * sizeof(u64)]);
if (conf.enable_fast_dispatch) {
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
code.jne(rsb_cache_miss);
} else {
code.jne(code.GetReturnFromRunCodeAddress());
@ -281,7 +281,7 @@ void A32EmitX64::GenTerminalHandlers() {
code.jmp(rax);
PerfMapRegister(terminal_handler_pop_rsb_hint, code.getCurr(), "a32_terminal_handler_pop_rsb_hint");
if (conf.enable_fast_dispatch) {
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
code.align();
terminal_handler_fast_dispatch_hint = code.getCurr<const void*>();
calculate_location_descriptor();
@ -1509,7 +1509,7 @@ void A32EmitX64::EmitSetUpperLocationDescriptor(IR::LocationDescriptor new_locat
void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor initial_location, bool is_single_step) {
EmitSetUpperLocationDescriptor(terminal.next, initial_location);
if (!conf.enable_optimizations || is_single_step) {
if (!conf.HasOptimization(OptimizationFlag::BlockLinking) || is_single_step) {
code.mov(MJitStateReg(A32::Reg::PC), A32::LocationDescriptor{terminal.next}.PC());
code.ReturnFromRunCode();
return;
@ -1538,7 +1538,7 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc
void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor initial_location, bool is_single_step) {
EmitSetUpperLocationDescriptor(terminal.next, initial_location);
if (!conf.enable_optimizations || is_single_step) {
if (!conf.HasOptimization(OptimizationFlag::BlockLinking) || is_single_step) {
code.mov(MJitStateReg(A32::Reg::PC), A32::LocationDescriptor{terminal.next}.PC());
code.ReturnFromRunCode();
return;
@ -1553,7 +1553,7 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::Location
}
void A32EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor, bool is_single_step) {
if (!conf.enable_optimizations || is_single_step) {
if (!conf.HasOptimization(OptimizationFlag::ReturnStackBuffer) || is_single_step) {
code.ReturnFromRunCode();
return;
}
@ -1562,11 +1562,12 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor,
}
void A32EmitX64::EmitTerminalImpl(IR::Term::FastDispatchHint, IR::LocationDescriptor, bool is_single_step) {
if (conf.enable_fast_dispatch && !is_single_step) {
code.jmp(terminal_handler_fast_dispatch_hint);
} else {
if (!conf.HasOptimization(OptimizationFlag::FastDispatch) || is_single_step) {
code.ReturnFromRunCode();
return;
}
code.jmp(terminal_handler_fast_dispatch_hint);
}
void A32EmitX64::EmitTerminalImpl(IR::Term::If terminal, IR::LocationDescriptor initial_location, bool is_single_step) {
@ -1624,7 +1625,7 @@ void A32EmitX64::EmitPatchMovRcx(CodePtr target_code_ptr) {
void A32EmitX64::Unpatch(const IR::LocationDescriptor& location) {
EmitX64::Unpatch(location);
if (conf.enable_fast_dispatch) {
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
(*fast_dispatch_table_lookup)(location.Value()) = {};
}
}

View file

@ -176,9 +176,11 @@ private:
}
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, [this](u32 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); }, {conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
if (conf.enable_optimizations) {
if (conf.HasOptimization(OptimizationFlag::GetSetElimination)) {
Optimization::A32GetSetElimination(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::ConstProp)) {
Optimization::A32ConstantMemoryReads(ir_block, conf.callbacks);
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);

View file

@ -140,7 +140,7 @@ void A64EmitX64::InvalidateCacheRanges(const boost::icl::interval_set<u64>& rang
}
void A64EmitX64::ClearFastDispatchTable() {
if (conf.enable_fast_dispatch) {
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
fast_dispatch_table.fill({});
}
}
@ -319,7 +319,7 @@ void A64EmitX64::GenTerminalHandlers() {
code.and_(eax, u32(A64JitState::RSBPtrMask));
code.mov(dword[r15 + offsetof(A64JitState, rsb_ptr)], eax);
code.cmp(rbx, qword[r15 + offsetof(A64JitState, rsb_location_descriptors) + rax * sizeof(u64)]);
if (conf.enable_fast_dispatch) {
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
code.jne(rsb_cache_miss);
} else {
code.jne(code.GetReturnFromRunCodeAddress());
@ -328,7 +328,7 @@ void A64EmitX64::GenTerminalHandlers() {
code.jmp(rax);
PerfMapRegister(terminal_handler_pop_rsb_hint, code.getCurr(), "a64_terminal_handler_pop_rsb_hint");
if (conf.enable_fast_dispatch) {
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
code.align();
terminal_handler_fast_dispatch_hint = code.getCurr<const void*>();
calculate_location_descriptor();
@ -362,7 +362,7 @@ void A64EmitX64::GenTerminalHandlers() {
}
void A64EmitX64::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
if (!conf.enable_optimizations) {
if (!conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
return;
}
@ -1212,7 +1212,7 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::ReturnToDispatch, IR::LocationDescri
}
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor, bool is_single_step) {
if (!conf.enable_optimizations || is_single_step) {
if (!conf.HasOptimization(OptimizationFlag::BlockLinking) || is_single_step) {
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC());
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax);
code.ReturnFromRunCode();
@ -1233,7 +1233,7 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc
}
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor, bool is_single_step) {
if (!conf.enable_optimizations || is_single_step) {
if (!conf.HasOptimization(OptimizationFlag::BlockLinking) || is_single_step) {
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC());
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax);
code.ReturnFromRunCode();
@ -1249,7 +1249,7 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::Location
}
void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor, bool is_single_step) {
if (!conf.enable_optimizations || is_single_step) {
if (!conf.HasOptimization(OptimizationFlag::ReturnStackBuffer) || is_single_step) {
code.ReturnFromRunCode();
return;
}
@ -1258,11 +1258,12 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor,
}
void A64EmitX64::EmitTerminalImpl(IR::Term::FastDispatchHint, IR::LocationDescriptor, bool is_single_step) {
if (conf.enable_fast_dispatch && !is_single_step) {
code.jmp(terminal_handler_fast_dispatch_hint);
} else {
if (!conf.HasOptimization(OptimizationFlag::FastDispatch) || is_single_step) {
code.ReturnFromRunCode();
return;
}
code.jmp(terminal_handler_fast_dispatch_hint);
}
void A64EmitX64::EmitTerminalImpl(IR::Term::If terminal, IR::LocationDescriptor initial_location, bool is_single_step) {
@ -1330,7 +1331,7 @@ void A64EmitX64::EmitPatchMovRcx(CodePtr target_code_ptr) {
void A64EmitX64::Unpatch(const IR::LocationDescriptor& location) {
EmitX64::Unpatch(location);
if (conf.enable_fast_dispatch) {
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
(*fast_dispatch_table_lookup)(location.Value()) = {};
}
}

View file

@ -249,14 +249,17 @@ private:
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{current_location}, get_code,
{conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
Optimization::A64CallbackConfigPass(ir_block, conf);
if (conf.enable_optimizations) {
if (conf.HasOptimization(OptimizationFlag::GetSetElimination)) {
Optimization::A64GetSetElimination(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::ConstProp)) {
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) {
Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks);
}
// printf("%s\n", IR::DumpBlock(ir_block).c_str());
Optimization::VerificationPass(ir_block);
return emitter.Emit(ir_block).entrypoint;
}