mirror of
https://github.com/open-goal/jak-project
synced 2026-09-03 02:14:07 -04:00
[decomp] clean up and make level-update-after-load work (#628)
* temp * make level-update-after-load work * add missing const
This commit is contained in:
@@ -577,6 +577,19 @@ bool ControlFlowGraph::is_goto_not_end_and_unreachable(CfgVtx* b0, CfgVtx* b1) {
|
||||
return true; // match!
|
||||
}
|
||||
|
||||
bool ControlFlowGraph::is_infinite_continue(CfgVtx* b0) {
|
||||
if (!b0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// end branch always.
|
||||
if (!b0->end_branch.has_branch || !b0->end_branch.branch_always || b0->end_branch.branch_likely) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ControlFlowGraph::is_goto_end_and_unreachable(CfgVtx* b0, CfgVtx* b1) {
|
||||
if (!b0 || !b1) {
|
||||
return false;
|
||||
@@ -848,6 +861,98 @@ bool ControlFlowGraph::find_goto_end() {
|
||||
return replaced;
|
||||
}
|
||||
|
||||
int get_prev_count(CfgVtx* start, CfgVtx* to_find) {
|
||||
int result = 0;
|
||||
while (start && start != to_find) {
|
||||
result++;
|
||||
start = start->prev;
|
||||
}
|
||||
|
||||
if (start == to_find) {
|
||||
return result;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ControlFlowGraph::find_infinite_continue() {
|
||||
bool replaced = false;
|
||||
|
||||
for_each_top_level_vtx([&](CfgVtx* vtx) {
|
||||
auto* b0 = vtx;
|
||||
if (is_infinite_continue(b0)) {
|
||||
int my_block = b0->get_first_block_id();
|
||||
int dest_block = b0->succ_branch->get_first_block_id();
|
||||
|
||||
fmt::print("Considering {} as an infinite continue:\n", b0->to_string());
|
||||
|
||||
if (dest_block >= my_block) {
|
||||
fmt::print(" Rejecting because destination block {} comes after me {}\n", dest_block,
|
||||
my_block);
|
||||
return true;
|
||||
} else {
|
||||
fmt::print(" Order OK {} -> {}\n", my_block, dest_block);
|
||||
}
|
||||
|
||||
int prev_count = get_prev_count(b0, b0->succ_branch);
|
||||
if (prev_count == -1) {
|
||||
fmt::print(
|
||||
" Rejecting because we can't find the destination in the current ungrouped sequence.");
|
||||
return true;
|
||||
} else {
|
||||
fmt::print(" Sequencing OK: {} prev's\n", prev_count);
|
||||
}
|
||||
replaced = true;
|
||||
|
||||
auto* new_goto = alloc<Break>();
|
||||
m_has_break = true;
|
||||
new_goto->body = b0;
|
||||
new_goto->unreachable_block = nullptr;
|
||||
new_goto->dest_block_id = b0->succ_branch->get_first_block_id();
|
||||
m_blocks.at(new_goto->dest_block_id)->needs_label = true;
|
||||
|
||||
// patch up thing -> goto branches
|
||||
for (auto* new_pred : b0->pred) {
|
||||
new_pred->replace_succ_and_check(b0, new_goto);
|
||||
}
|
||||
new_goto->pred = b0->pred;
|
||||
|
||||
assert(b0->succs().size() == 1 && b0->succs().front() == b0->succ_branch);
|
||||
|
||||
// patch up next and prev.
|
||||
new_goto->next = b0->next;
|
||||
if (new_goto->next) {
|
||||
assert(new_goto->next->prev == b0);
|
||||
new_goto->next->prev = new_goto;
|
||||
}
|
||||
new_goto->prev = b0->prev;
|
||||
if (new_goto->prev) {
|
||||
assert(new_goto->prev->next == b0);
|
||||
new_goto->prev->next = new_goto;
|
||||
}
|
||||
|
||||
// now we want to make it look like the goto will fall through to next.
|
||||
if (new_goto->next) {
|
||||
// now we will fall through
|
||||
new_goto->succ_ft = b0->next;
|
||||
assert(!new_goto->succ_ft->has_pred(new_goto));
|
||||
new_goto->succ_ft->pred.push_back(new_goto);
|
||||
assert(!new_goto->succ_branch);
|
||||
}
|
||||
|
||||
// break goto preds.
|
||||
b0->succ_branch->replace_preds_with_and_check({b0}, nullptr);
|
||||
|
||||
b0->parent_claim(new_goto);
|
||||
return false;
|
||||
}
|
||||
|
||||
// keep looking
|
||||
return true;
|
||||
});
|
||||
|
||||
return replaced;
|
||||
}
|
||||
|
||||
bool ControlFlowGraph::find_goto_not_end() {
|
||||
bool replaced = false;
|
||||
|
||||
@@ -2132,6 +2237,7 @@ std::shared_ptr<ControlFlowGraph> build_cfg(const LinkedObjectFile& file,
|
||||
cfg->flag_early_exit(func.basic_blocks);
|
||||
|
||||
bool changed = true;
|
||||
bool complained_about_weird_gotos = false;
|
||||
while (changed) {
|
||||
changed = false;
|
||||
// note - we should prioritize finding short-circuiting expressions.
|
||||
@@ -2164,7 +2270,14 @@ std::shared_ptr<ControlFlowGraph> build_cfg(const LinkedObjectFile& file,
|
||||
|
||||
if (!changed) {
|
||||
changed = changed || cfg->find_cond_w_empty_else();
|
||||
if (changed) {
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
changed = changed || cfg->find_infinite_continue();
|
||||
if (changed && !complained_about_weird_gotos) {
|
||||
complained_about_weird_gotos = true;
|
||||
func.warnings.general_warning(
|
||||
"Found some very strange gotos. Check result carefully, this is not well tested.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user