mirror of
https://github.com/open-goal/jak-project
synced 2026-07-11 15:28:58 -04:00
[gcommon decomp] compiler and decompiler fixes (#239)
* wip * decompile file-io * a * fix
This commit is contained in:
@@ -150,6 +150,30 @@ void clean_up_return(FormPool& pool, ReturnElement* ir) {
|
||||
}
|
||||
}
|
||||
|
||||
void clean_up_return_final(const Function& f, ReturnElement* ir) {
|
||||
SetVarElement* dead = dynamic_cast<SetVarElement*>(ir->dead_code->try_as_single_element());
|
||||
if (!dead) {
|
||||
dead = dynamic_cast<SetVarElement*>(ir->dead_code->elts().front());
|
||||
for (int i = 1; i < ir->dead_code->size(); i++) {
|
||||
if (!dynamic_cast<EmptyElement*>(ir->dead_code->at(i))) {
|
||||
dead = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dead) {
|
||||
lg::error("failed to recognize dead code after return, got {}",
|
||||
ir->dead_code->to_string(f.ir2.env));
|
||||
}
|
||||
assert(dead);
|
||||
auto src = dynamic_cast<SimpleExpressionElement*>(dead->src()->try_as_single_element());
|
||||
assert(src);
|
||||
assert(src->expr().is_identity() && src->expr().get_arg(0).is_int() &&
|
||||
src->expr().get_arg(0).get_int() == 0);
|
||||
ir->dead_code = nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Remove the branch in a break (really return-from nonfunction scope)
|
||||
*/
|
||||
@@ -1355,8 +1379,22 @@ Form* cfg_to_ir(FormPool& pool, Function& f, const CfgVtx* vtx) {
|
||||
return result;
|
||||
} else if (dynamic_cast<const GotoEnd*>(vtx)) {
|
||||
auto* cvtx = dynamic_cast<const GotoEnd*>(vtx);
|
||||
|
||||
// dead code should always be (set! var 0)
|
||||
auto dead_code = cfg_to_ir(pool, f, cvtx->unreachable_block);
|
||||
// auto dead = dynamic_cast<SetVarElement*>(dead_code->try_as_single_element());
|
||||
// if (!dead) {
|
||||
// lg::error("failed to recognize dead code after return, got {}",
|
||||
// dead_code->to_string(f.ir2.env));
|
||||
// }
|
||||
// assert(dead);
|
||||
// auto src = dynamic_cast<SimpleExpressionElement*>(dead->src()->try_as_single_element());
|
||||
// assert(src);
|
||||
// assert(src->expr().is_identity() && src->expr().get_arg(0).is_int() &&
|
||||
// src->expr().get_arg(0).get_int() == 0);
|
||||
|
||||
auto result = pool.alloc_single_element_form<ReturnElement>(
|
||||
nullptr, cfg_to_ir(pool, f, cvtx->body), cfg_to_ir(pool, f, cvtx->unreachable_block));
|
||||
nullptr, cfg_to_ir(pool, f, cvtx->body), dead_code);
|
||||
clean_up_return(pool, dynamic_cast<ReturnElement*>(result->try_as_single_element()));
|
||||
return result;
|
||||
} else if (dynamic_cast<const Break*>(vtx)) {
|
||||
@@ -1433,6 +1471,11 @@ void build_initial_forms(Function& function) {
|
||||
if (as_cne) {
|
||||
clean_up_cond_no_else_final(function, as_cne);
|
||||
}
|
||||
|
||||
auto as_return = dynamic_cast<ReturnElement*>(form);
|
||||
if (as_return) {
|
||||
clean_up_return_final(function, as_return);
|
||||
}
|
||||
});
|
||||
|
||||
function.ir2.top_form = result;
|
||||
|
||||
Reference in New Issue
Block a user