[decommp] generic-obs (#2013)

This commit is contained in:
water111
2022-11-12 17:56:07 -05:00
committed by GitHub
parent 84ef64398e
commit f39b993f79
165 changed files with 12536 additions and 6261 deletions
+37 -30
View File
@@ -652,18 +652,37 @@ void SSA::remap(int) {
}
namespace {
TP_Type lca_for_var_types(const TP_Type& existing,
const TP_Type& add,
const DecompilerTypeSystem& dts,
bool event_handler_hack) {
bool changed;
auto normal = dts.tp_lca(existing, add, &changed);
if (!event_handler_hack || normal.typespec().base_type() != "none") {
return normal;
}
if (existing.typespec().base_type() == "none") {
return add;
} else if (add.typespec().base_type() == "none") {
return existing;
} else {
return normal;
}
}
void update_var_info(VariableNames::VarInfo* info,
Register reg,
const TypeState& ts,
int var_id,
const DecompilerTypeSystem& dts) {
const DecompilerTypeSystem& dts,
bool event_handler_hack) {
auto& type = ts.get(reg);
if (info->initialized) {
ASSERT(info->reg_id.id == var_id);
ASSERT(info->reg_id.reg == reg);
bool changed;
info->type = dts.tp_lca(info->type, type, &changed);
info->type = lca_for_var_types(info->type, type, dts, event_handler_hack);
} else {
info->reg_id.id = var_id;
@@ -676,10 +695,11 @@ void update_var_info(VariableNames::VarInfo* info,
bool merge_infos(VariableNames::VarInfo* info1,
VariableNames::VarInfo* info2,
const DecompilerTypeSystem& dts) {
const DecompilerTypeSystem& dts,
bool event_handler_hack) {
if (info1->initialized && info2->initialized) {
bool changed;
auto new_type = dts.tp_lca(info1->type, info2->type, &changed);
auto new_type = lca_for_var_types(info1->type, info2->type, dts, event_handler_hack);
info1->type = new_type;
info2->type = new_type;
return true;
@@ -690,12 +710,13 @@ bool merge_infos(VariableNames::VarInfo* info1,
void merge_infos(
std::unordered_map<Register, std::vector<VariableNames::VarInfo>, Register::hash>& info1,
std::unordered_map<Register, std::vector<VariableNames::VarInfo>, Register::hash>& info2,
const DecompilerTypeSystem& dts) {
const DecompilerTypeSystem& dts,
bool event_handler_hack) {
for (auto& [reg, infos] : info1) {
auto other = info2.find(reg);
if (other != info2.end()) {
for (size_t i = 0; i < std::min(other->second.size(), infos.size()); i++) {
merge_infos(&infos.at(i), &other->second.at(i), dts);
merge_infos(&infos.at(i), &other->second.at(i), dts, event_handler_hack);
}
}
}
@@ -704,8 +725,13 @@ void merge_infos(
/*!
* Create variable info for each variable.
* Note: the "event_handler_hack" is supposed to help with the use of "none" typed variables
* that are actually used. It's a hack because we don't really have enough information to know if
* the none variables
*/
void SSA::make_vars(const Function& function, const DecompilerTypeSystem& dts) {
bool event_handler_hack =
function.ir2.env.version > GameVersion::Jak1 && function.guessed_name.is_event_handler();
for (int block_id = 0; block_id < int(blocks.size()); block_id++) {
const auto& block = blocks.at(block_id);
const TypeState* init_types = &function.ir2.env.get_types_at_block_entry(block_id);
@@ -720,13 +746,13 @@ void SSA::make_vars(const Function& function, const DecompilerTypeSystem& dts) {
if (instr.dst.has_value()) {
auto var_id = map.var_id(*instr.dst);
auto* info = &program_write_vars[instr.dst->reg()].at(var_id);
update_var_info(info, instr.dst->reg(), *end_types, var_id, dts);
update_var_info(info, instr.dst->reg(), *end_types, var_id, dts, event_handler_hack);
}
for (auto& src : instr.src) {
auto var_id = map.var_id(src);
auto* info = &program_read_vars[src.reg()].at(var_id);
update_var_info(info, src.reg(), *init_types, var_id, dts);
update_var_info(info, src.reg(), *init_types, var_id, dts, event_handler_hack);
}
init_types = end_types;
@@ -747,26 +773,7 @@ void SSA::make_vars(const Function& function, const DecompilerTypeSystem& dts) {
}
}
// if (function.type.last_arg() != TypeSpec("none")) {
// auto return_var = function.ir2.atomic_ops->end_op().return_var();
// auto return_reg = return_var.reg();
// const auto& last_block = blocks.at(blocks.size() - 1);
// const auto& last_ins = last_block.ins.at(last_block.ins.size() - 1);
// ASSERT(last_ins.src.size() == 1);
// auto return_idx = map.var_id(last_ins.src.at(0));
//
// if (!program_read_vars[return_reg].empty()) {
// program_read_vars[return_reg].at(return_idx).type =
// TP_Type::make_from_ts(function.type.last_arg());
// }
//
// if (!program_write_vars[return_reg].empty()) {
// program_write_vars[return_reg].at(return_idx).type =
// TP_Type::make_from_ts(function.type.last_arg());
// }
// }
merge_infos(program_write_vars, program_read_vars, dts);
merge_infos(program_write_vars, program_read_vars, dts, event_handler_hack);
// copy types from input argument coloring moves:
for (auto& instr : blocks.at(0).ins) {