ir_opt: Add IdentityRemovalPass

This commit is contained in:
MerryMage 2020-04-20 16:12:19 +01:00
parent 2ae68b13ed
commit 996d5cb841
3 changed files with 49 additions and 1 deletions

View file

@ -95,6 +95,7 @@ add_library(dynarmic
frontend/ir/value.h frontend/ir/value.h
ir_opt/constant_propagation_pass.cpp ir_opt/constant_propagation_pass.cpp
ir_opt/dead_code_elimination_pass.cpp ir_opt/dead_code_elimination_pass.cpp
ir_opt/identity_removal_pass.cpp
ir_opt/passes.h ir_opt/passes.h
ir_opt/verification_pass.cpp ir_opt/verification_pass.cpp
) )

View file

@ -0,0 +1,46 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2020 MerryMage
* This software may be used and distributed according to the terms of the GNU
* General Public License version 2 or any later version.
*/
#include <vector>
#include "common/iterator_util.h"
#include "frontend/ir/basic_block.h"
#include "frontend/ir/opcodes.h"
#include "ir_opt/passes.h"
namespace Dynarmic::Optimization {
void IdentityRemovalPass(IR::Block& block) {
std::vector<IR::Inst*> to_invalidate;
auto iter = block.begin();
while (iter != block.end()) {
IR::Inst& inst = *iter;
const size_t num_args = inst.NumArgs();
for (size_t i = 0; i < num_args; i++) {
while (true) {
IR::Value arg = inst.GetArg(i);
if (!arg.IsIdentity())
break;
inst.SetArg(i, arg.GetInst()->GetArg(0));
}
}
if (inst.GetOpcode() == IR::Opcode::Identity) {
iter = block.Instructions().erase(inst);
to_invalidate.push_back(&inst);
} else {
++iter;
}
}
for (IR::Inst* inst : to_invalidate) {
inst->Invalidate();
}
}
} // namespace Dynarmic

View file

@ -21,13 +21,14 @@ class Block;
namespace Dynarmic::Optimization { namespace Dynarmic::Optimization {
void A32GetSetElimination(IR::Block& block);
void A32ConstantMemoryReads(IR::Block& block, A32::UserCallbacks* cb); void A32ConstantMemoryReads(IR::Block& block, A32::UserCallbacks* cb);
void A32GetSetElimination(IR::Block& block);
void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf); void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf);
void A64GetSetElimination(IR::Block& block); void A64GetSetElimination(IR::Block& block);
void A64MergeInterpretBlocksPass(IR::Block& block, A64::UserCallbacks* cb); void A64MergeInterpretBlocksPass(IR::Block& block, A64::UserCallbacks* cb);
void ConstantPropagation(IR::Block& block); void ConstantPropagation(IR::Block& block);
void DeadCodeElimination(IR::Block& block); void DeadCodeElimination(IR::Block& block);
void IdentityRemovalPass(IR::Block& block);
void VerificationPass(const IR::Block& block); void VerificationPass(const IR::Block& block);
} // namespace Dynarmic::Optimization } // namespace Dynarmic::Optimization