#include "source/opt/local_redundancy_elimination.h"
#include "source/opt/value_number_table.h"
namespace spvtools {
namespace opt {
Pass::Status LocalRedundancyEliminationPass::Process() {
bool modified = false;
ValueNumberTable vnTable(context());
for (auto& func : *get_module()) {
for (auto& bb : func) {
std::map<uint32_t, uint32_t> value_to_ids;
if (EliminateRedundanciesInBB(&bb, vnTable, &value_to_ids))
modified = true;
}
}
return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
}
bool LocalRedundancyEliminationPass::EliminateRedundanciesInBB(
BasicBlock* block, const ValueNumberTable& vnTable,
std::map<uint32_t, uint32_t>* value_to_ids) {
bool modified = false;
auto func = [this, &vnTable, &modified, value_to_ids](Instruction* inst) {
if (inst->result_id() == 0) {
return;
}
uint32_t value = vnTable.GetValueNumber(inst);
if (value == 0) {
return;
}
auto candidate = value_to_ids->insert({value, inst->result_id()});
if (!candidate.second) {
context()->KillNamesAndDecorates(inst);
context()->ReplaceAllUsesWith(inst->result_id(), candidate.first->second);
context()->KillInst(inst);
modified = true;
}
};
block->ForEachInst(func);
return modified;
}
}
}