Merge pull request #468 from lioncash/const

ir_opt: Mark locals as const where applicable
This commit is contained in:
Merry 2019-04-12 19:15:32 +01:00 committed by MerryMage
commit 4a3d808354
4 changed files with 38 additions and 33 deletions

View file

@ -16,52 +16,56 @@ void A32ConstantMemoryReads(IR::Block& block, A32::UserCallbacks* cb) {
for (auto& inst : block) { for (auto& inst : block) {
switch (inst.GetOpcode()) { switch (inst.GetOpcode()) {
case IR::Opcode::A32SetCFlag: { case IR::Opcode::A32SetCFlag: {
IR::Value arg = inst.GetArg(0); const IR::Value arg = inst.GetArg(0);
if (!arg.IsImmediate() && arg.GetInst()->GetOpcode() == IR::Opcode::A32GetCFlag) { if (!arg.IsImmediate() && arg.GetInst()->GetOpcode() == IR::Opcode::A32GetCFlag) {
inst.Invalidate(); inst.Invalidate();
} }
break; break;
} }
case IR::Opcode::A32ReadMemory8: { case IR::Opcode::A32ReadMemory8: {
if (!inst.AreAllArgsImmediates()) if (!inst.AreAllArgsImmediates()) {
break; break;
}
u32 vaddr = inst.GetArg(0).GetU32(); const u32 vaddr = inst.GetArg(0).GetU32();
if (cb->IsReadOnlyMemory(vaddr)) { if (cb->IsReadOnlyMemory(vaddr)) {
u8 value_from_memory = cb->MemoryRead8(vaddr); const u8 value_from_memory = cb->MemoryRead8(vaddr);
inst.ReplaceUsesWith(IR::Value{value_from_memory}); inst.ReplaceUsesWith(IR::Value{value_from_memory});
} }
break; break;
} }
case IR::Opcode::A32ReadMemory16: { case IR::Opcode::A32ReadMemory16: {
if (!inst.AreAllArgsImmediates()) if (!inst.AreAllArgsImmediates()) {
break; break;
}
u32 vaddr = inst.GetArg(0).GetU32(); const u32 vaddr = inst.GetArg(0).GetU32();
if (cb->IsReadOnlyMemory(vaddr)) { if (cb->IsReadOnlyMemory(vaddr)) {
u16 value_from_memory = cb->MemoryRead16(vaddr); const u16 value_from_memory = cb->MemoryRead16(vaddr);
inst.ReplaceUsesWith(IR::Value{value_from_memory}); inst.ReplaceUsesWith(IR::Value{value_from_memory});
} }
break; break;
} }
case IR::Opcode::A32ReadMemory32: { case IR::Opcode::A32ReadMemory32: {
if (!inst.AreAllArgsImmediates()) if (!inst.AreAllArgsImmediates()) {
break; break;
}
u32 vaddr = inst.GetArg(0).GetU32(); const u32 vaddr = inst.GetArg(0).GetU32();
if (cb->IsReadOnlyMemory(vaddr)) { if (cb->IsReadOnlyMemory(vaddr)) {
u32 value_from_memory = cb->MemoryRead32(vaddr); const u32 value_from_memory = cb->MemoryRead32(vaddr);
inst.ReplaceUsesWith(IR::Value{value_from_memory}); inst.ReplaceUsesWith(IR::Value{value_from_memory});
} }
break; break;
} }
case IR::Opcode::A32ReadMemory64: { case IR::Opcode::A32ReadMemory64: {
if (!inst.AreAllArgsImmediates()) if (!inst.AreAllArgsImmediates()) {
break; break;
}
u32 vaddr = inst.GetArg(0).GetU32(); const u32 vaddr = inst.GetArg(0).GetU32();
if (cb->IsReadOnlyMemory(vaddr)) { if (cb->IsReadOnlyMemory(vaddr)) {
u64 value_from_memory = cb->MemoryRead64(vaddr); const u64 value_from_memory = cb->MemoryRead64(vaddr);
inst.ReplaceUsesWith(IR::Value{value_from_memory}); inst.ReplaceUsesWith(IR::Value{value_from_memory});
} }
break; break;

View file

@ -56,48 +56,49 @@ void A32GetSetElimination(IR::Block& block) {
for (auto inst = block.begin(); inst != block.end(); ++inst) { for (auto inst = block.begin(); inst != block.end(); ++inst) {
switch (inst->GetOpcode()) { switch (inst->GetOpcode()) {
case IR::Opcode::A32SetRegister: { case IR::Opcode::A32SetRegister: {
A32::Reg reg = inst->GetArg(0).GetA32RegRef(); const A32::Reg reg = inst->GetArg(0).GetA32RegRef();
if (reg == A32::Reg::PC) if (reg == A32::Reg::PC) {
break; break;
size_t reg_index = static_cast<size_t>(reg); }
const auto reg_index = static_cast<size_t>(reg);
do_set(reg_info[reg_index], inst->GetArg(1), inst); do_set(reg_info[reg_index], inst->GetArg(1), inst);
break; break;
} }
case IR::Opcode::A32GetRegister: { case IR::Opcode::A32GetRegister: {
A32::Reg reg = inst->GetArg(0).GetA32RegRef(); const A32::Reg reg = inst->GetArg(0).GetA32RegRef();
ASSERT(reg != A32::Reg::PC); ASSERT(reg != A32::Reg::PC);
size_t reg_index = static_cast<size_t>(reg); const size_t reg_index = static_cast<size_t>(reg);
do_get(reg_info[reg_index], inst); do_get(reg_info[reg_index], inst);
break; break;
} }
case IR::Opcode::A32SetExtendedRegister32: { case IR::Opcode::A32SetExtendedRegister32: {
A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
size_t reg_index = A32::RegNumber(reg); const size_t reg_index = A32::RegNumber(reg);
do_set(ext_reg_singles_info[reg_index], inst->GetArg(1), inst); do_set(ext_reg_singles_info[reg_index], inst->GetArg(1), inst);
size_t doubles_reg_index = reg_index / 2; const size_t doubles_reg_index = reg_index / 2;
if (doubles_reg_index < ext_reg_doubles_info.size()) { if (doubles_reg_index < ext_reg_doubles_info.size()) {
ext_reg_doubles_info[doubles_reg_index] = {}; ext_reg_doubles_info[doubles_reg_index] = {};
} }
break; break;
} }
case IR::Opcode::A32GetExtendedRegister32: { case IR::Opcode::A32GetExtendedRegister32: {
A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
size_t reg_index = A32::RegNumber(reg); const size_t reg_index = A32::RegNumber(reg);
do_get(ext_reg_singles_info[reg_index], inst); do_get(ext_reg_singles_info[reg_index], inst);
size_t doubles_reg_index = reg_index / 2; const size_t doubles_reg_index = reg_index / 2;
if (doubles_reg_index < ext_reg_doubles_info.size()) { if (doubles_reg_index < ext_reg_doubles_info.size()) {
ext_reg_doubles_info[doubles_reg_index] = {}; ext_reg_doubles_info[doubles_reg_index] = {};
} }
break; break;
} }
case IR::Opcode::A32SetExtendedRegister64: { case IR::Opcode::A32SetExtendedRegister64: {
A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
size_t reg_index = A32::RegNumber(reg); const size_t reg_index = A32::RegNumber(reg);
do_set(ext_reg_doubles_info[reg_index], inst->GetArg(1), inst); do_set(ext_reg_doubles_info[reg_index], inst->GetArg(1), inst);
size_t singles_reg_index = reg_index * 2; const size_t singles_reg_index = reg_index * 2;
if (singles_reg_index < ext_reg_singles_info.size()) { if (singles_reg_index < ext_reg_singles_info.size()) {
ext_reg_singles_info[singles_reg_index] = {}; ext_reg_singles_info[singles_reg_index] = {};
ext_reg_singles_info[singles_reg_index+1] = {}; ext_reg_singles_info[singles_reg_index+1] = {};
@ -105,11 +106,11 @@ void A32GetSetElimination(IR::Block& block) {
break; break;
} }
case IR::Opcode::A32GetExtendedRegister64: { case IR::Opcode::A32GetExtendedRegister64: {
A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
size_t reg_index = A32::RegNumber(reg); const size_t reg_index = A32::RegNumber(reg);
do_get(ext_reg_doubles_info[reg_index], inst); do_get(ext_reg_doubles_info[reg_index], inst);
size_t singles_reg_index = reg_index * 2; const size_t singles_reg_index = reg_index * 2;
if (singles_reg_index < ext_reg_singles_info.size()) { if (singles_reg_index < ext_reg_singles_info.size()) {
ext_reg_singles_info[singles_reg_index] = {}; ext_reg_singles_info[singles_reg_index] = {};
ext_reg_singles_info[singles_reg_index+1] = {}; ext_reg_singles_info[singles_reg_index+1] = {};

View file

@ -25,7 +25,7 @@ void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf) {
continue; continue;
} }
auto op = static_cast<A64::DataCacheOperation>(inst.GetArg(0).GetU64()); const auto op = static_cast<A64::DataCacheOperation>(inst.GetArg(0).GetU64());
if (op == A64::DataCacheOperation::ZeroByVA) { if (op == A64::DataCacheOperation::ZeroByVA) {
A64::IREmitter ir{block}; A64::IREmitter ir{block};
ir.SetInsertionPoint(&inst); ir.SetInsertionPoint(&inst);

View file

@ -19,8 +19,8 @@ namespace Dynarmic::Optimization {
void VerificationPass(const IR::Block& block) { void VerificationPass(const IR::Block& block) {
for (const auto& inst : block) { for (const auto& inst : block) {
for (size_t i = 0; i < inst.NumArgs(); i++) { for (size_t i = 0; i < inst.NumArgs(); i++) {
IR::Type t1 = inst.GetArg(i).GetType(); const IR::Type t1 = inst.GetArg(i).GetType();
IR::Type t2 = IR::GetArgTypeOf(inst.GetOpcode(), i); const IR::Type t2 = IR::GetArgTypeOf(inst.GetOpcode(), i);
if (!IR::AreTypesCompatible(t1, t2)) { if (!IR::AreTypesCompatible(t1, t2)) {
puts(IR::DumpBlock(block).c_str()); puts(IR::DumpBlock(block).c_str());
ASSERT(false); ASSERT(false);