A64: Add enable_optimizations configuration option
Allow library users to disable optimizations for debugging reasons.
This commit is contained in:
parent
8bef1afb9a
commit
0c51313479
4 changed files with 42 additions and 4 deletions
|
@ -116,6 +116,14 @@ struct UserConfig {
|
||||||
size_t processor_id = 0;
|
size_t processor_id = 0;
|
||||||
ExclusiveMonitor* global_monitor = nullptr;
|
ExclusiveMonitor* global_monitor = nullptr;
|
||||||
|
|
||||||
|
/// When set to false, this disables all optimizations than can't otherwise be disabled
|
||||||
|
/// by setting other configuration options. This includes:
|
||||||
|
/// - IR optimizations
|
||||||
|
/// - Block linking optimizations
|
||||||
|
/// - RSB optimizations
|
||||||
|
/// This is intended to be used for debugging.
|
||||||
|
bool enable_optimizations = true;
|
||||||
|
|
||||||
/// When set to true, UserCallbacks::DataCacheOperationRaised will be called when any
|
/// When set to true, UserCallbacks::DataCacheOperationRaised will be called when any
|
||||||
/// data cache instruction is executed. Notably DC ZVA will not implicitly do anything.
|
/// data cache instruction is executed. Notably DC ZVA will not implicitly do anything.
|
||||||
/// When set to false, UserCallbacks::DataCacheOperationRaised will never be called.
|
/// When set to false, UserCallbacks::DataCacheOperationRaised will never be called.
|
||||||
|
|
|
@ -350,6 +350,14 @@ void A64EmitX64::GenTerminalHandlers() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void A64EmitX64::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
if (!conf.enable_optimizations) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitX64::EmitPushRSB(ctx, inst);
|
||||||
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitA64SetCheckBit(A64EmitContext& ctx, IR::Inst* inst) {
|
void A64EmitX64::EmitA64SetCheckBit(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Reg8 to_store = ctx.reg_alloc.UseGpr(args[0]).cvt8();
|
const Xbyak::Reg8 to_store = ctx.reg_alloc.UseGpr(args[0]).cvt8();
|
||||||
|
@ -1156,6 +1164,13 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::ReturnToDispatch, IR::LocationDescri
|
||||||
}
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor) {
|
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor) {
|
||||||
|
if (!conf.enable_optimizations) {
|
||||||
|
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC());
|
||||||
|
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax);
|
||||||
|
code.ReturnFromRunCode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
code.cmp(qword[r15 + offsetof(A64JitState, cycles_remaining)], 0);
|
code.cmp(qword[r15 + offsetof(A64JitState, cycles_remaining)], 0);
|
||||||
|
|
||||||
patch_information[terminal.next].jg.emplace_back(code.getCurr());
|
patch_information[terminal.next].jg.emplace_back(code.getCurr());
|
||||||
|
@ -1170,6 +1185,13 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc
|
||||||
}
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor) {
|
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor) {
|
||||||
|
if (!conf.enable_optimizations) {
|
||||||
|
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC());
|
||||||
|
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax);
|
||||||
|
code.ReturnFromRunCode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
patch_information[terminal.next].jmp.emplace_back(code.getCurr());
|
patch_information[terminal.next].jmp.emplace_back(code.getCurr());
|
||||||
if (auto next_bb = GetBasicBlock(terminal.next)) {
|
if (auto next_bb = GetBasicBlock(terminal.next)) {
|
||||||
EmitPatchJmp(terminal.next, next_bb->entrypoint);
|
EmitPatchJmp(terminal.next, next_bb->entrypoint);
|
||||||
|
@ -1179,6 +1201,11 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::Location
|
||||||
}
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor) {
|
void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor) {
|
||||||
|
if (!conf.enable_optimizations) {
|
||||||
|
code.ReturnFromRunCode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
code.jmp(terminal_handler_pop_rsb_hint);
|
code.jmp(terminal_handler_pop_rsb_hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ protected:
|
||||||
void EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t bitsize);
|
void EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t bitsize);
|
||||||
|
|
||||||
// Microinstruction emitters
|
// Microinstruction emitters
|
||||||
|
void EmitPushRSB(EmitContext& ctx, IR::Inst* inst);
|
||||||
#define OPCODE(...)
|
#define OPCODE(...)
|
||||||
#define A32OPC(...)
|
#define A32OPC(...)
|
||||||
#define A64OPC(name, type, ...) void EmitA64##name(A64EmitContext& ctx, IR::Inst* inst);
|
#define A64OPC(name, type, ...) void EmitA64##name(A64EmitContext& ctx, IR::Inst* inst);
|
||||||
|
|
|
@ -231,10 +231,12 @@ private:
|
||||||
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
|
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});
|
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{current_location}, get_code, {conf.define_unpredictable_behaviour});
|
||||||
Optimization::A64CallbackConfigPass(ir_block, conf);
|
Optimization::A64CallbackConfigPass(ir_block, conf);
|
||||||
Optimization::A64GetSetElimination(ir_block);
|
if (conf.enable_optimizations) {
|
||||||
Optimization::ConstantPropagation(ir_block);
|
Optimization::A64GetSetElimination(ir_block);
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::ConstantPropagation(ir_block);
|
||||||
Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks);
|
||||||
|
}
|
||||||
// printf("%s\n", IR::DumpBlock(ir_block).c_str());
|
// printf("%s\n", IR::DumpBlock(ir_block).c_str());
|
||||||
Optimization::VerificationPass(ir_block);
|
Optimization::VerificationPass(ir_block);
|
||||||
return emitter.Emit(ir_block).entrypoint;
|
return emitter.Emit(ir_block).entrypoint;
|
||||||
|
|
Loading…
Reference in a new issue