fix sc when the block after the delay slot is optimized out (#721)

This commit is contained in:
water111
2021-07-25 16:42:37 -04:00
committed by GitHub
parent f6534c2f3a
commit 92a5d84a5b
6 changed files with 127 additions and 17 deletions
@@ -3263,8 +3263,14 @@ void ShortCircuitElement::push_to_stack(const Env& env, FormPool& pool, FormStac
entry.condition->clear();
for (auto e : new_entries) {
if (dynamic_cast<EmptyElement*>(e)) {
continue;
}
entry.condition->push_back(e);
}
if (entry.condition->elts().empty()) {
entry.condition->push_back(pool.alloc_element<EmptyElement>());
}
}
}
+8 -4
View File
@@ -611,7 +611,14 @@ bool try_splitting_nested_sc(FormPool& pool, Function& func, ShortCircuitElement
* if there is a case like (and a (or b c))
*/
void clean_up_sc(FormPool& pool, Function& func, ShortCircuitElement* ir) {
assert(ir->entries.size() > 1);
assert(ir->entries.size() > 0);
if (ir->entries.size() == 1) {
// need to fake the final entry.
ShortCircuitElement::Entry empty_final;
empty_final.condition = pool.alloc_single_element_form<EmptyElement>(ir);
ir->entries.push_back(empty_final);
}
if (!try_clean_up_sc_as_and(pool, func, ir)) {
if (!try_clean_up_sc_as_or(pool, func, ir)) {
if (!try_splitting_nested_sc(pool, func, ir)) {
@@ -1615,9 +1622,6 @@ Form* cfg_to_ir_helper(FormPool& pool, Function& f, const CfgVtx* vtx) {
return as_abs;
}
if (svtx->entries.size() == 1) {
throw std::runtime_error("Weird short circuit form.");
}
// now try as a normal and/or
std::vector<ShortCircuitElement::Entry> entries;
for (auto& x : svtx->entries) {
@@ -377,9 +377,6 @@
"ocean-generate-verts",
"ocean-interp-wave",
// anim-tester BUG
//"anim-tester-add-newobj",
// nav-enemy BUG
"(anon-function 28 nav-enemy)",
+2 -2
View File
@@ -252,7 +252,7 @@
(while iter
(let ((proc (-> (the entity-links (-> iter extra)) process)))
(when proc
(set! result (and result (send-event proc message)))
(set! result (or (send-event proc message) result))
)
(set! iter (entity-actor-lookup iter 'next-actor 0))
)
@@ -269,7 +269,7 @@
(while iter
(let ((proc (-> (the entity-links (-> iter extra)) process)))
(when proc
(set! result (and result (send-event proc message)))
(set! result (or (send-event proc message) result))
)
(set! iter (entity-actor-lookup iter 'prev-actor 0))
)
@@ -248,11 +248,8 @@
(set! (-> msg-block from) pp)
(set! (-> msg-block num-params) 0)
(set! (-> msg-block message) message)
(let ((v1-3 (send-event-function proc msg-block)))
(b! v1-3 cfg-4 :likely-delay (set! result v1-3))
)
(set! result (or (send-event-function proc msg-block) result))
)
(label cfg-4)
)
)
(set! iter (entity-actor-lookup iter 'next-actor 0))
@@ -278,11 +275,8 @@
(set! (-> a1-1 from) pp)
(set! (-> a1-1 num-params) 0)
(set! (-> a1-1 message) arg0)
(let ((v1-3 (send-event-function a0-1 a1-1)))
(b! v1-3 cfg-4 :likely-delay (set! s5-0 v1-3))
)
(set! s5-0 (or (send-event-function a0-1 a1-1) s5-0))
)
(label cfg-4)
)
)
(set! s4-0 (entity-actor-lookup s4-0 'prev-actor 0))
@@ -53,4 +53,113 @@ TEST_F(FormRegressionTest, VectorDegToVectorRad) {
" )\n"
" )";
test_final_function(func, type, expected);
}
// weird short circuit thing
TEST_F(FormRegressionTest, WeirdShortCircuit) {
std::string func =
"sll r0, r0, 0\n"
" daddiu sp, sp, -144\n"
" sd ra, 0(sp)\n"
" sq s4, 96(sp)\n"
" sq s5, 112(sp)\n"
" sq gp, 128(sp)\n"
" or gp, a1, r0\n"
" or v1, a0, r0\n"
" lwu s4, 4(v1)\n"
" or s5, s7, r0\n" // s5 = result
" beq r0, r0, L43\n"
" sll r0, r0, 0\n"
"L40:\n"
" lwu v1, 20(s4)\n"
" lwu a0, 12(v1)\n"
" beq s7, a0, L42\n"
" or v1, s7, r0\n"
" daddiu a1, sp, 16\n"
" sw s6, 4(a1)\n"
" sw r0, 8(a1)\n"
" sw gp, 12(a1)\n"
" lw t9, send-event-function(s7)\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" or v1, v0, r0\n"
" bnel s7, v1, L41\n"
" or s5, v1, r0\n"
// there's nothing here!
"L41:\n"
" or v1, s5, r0\n"
"L42:\n"
" lw t9, entity-actor-lookup(s7)\n"
" daddiu a1, s7, next-actor\n"
" addiu a2, r0, 0\n"
" or a0, s4, r0\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" or v1, v0, r0\n"
" or s4, v1, r0\n"
"L43:\n"
" bne s7, s4, L40\n"
" sll r0, r0, 0\n"
" or v1, s7, r0\n"
" or v0, s5, r0\n"
" ld ra, 0(sp)\n"
" lq gp, 128(sp)\n"
" lq s5, 112(sp)\n"
" lq s4, 96(sp)\n"
" jr ra\n"
" daddiu sp, sp, 144";
std::string type = "(function actor-link-info symbol object)";
std::string expected =
"(let ((s4-0 (-> arg0 next))\n"
" (s5-0 (the-as object #f))\n"
" )\n"
" (while s4-0\n"
" (let ((a0-1 (-> s4-0 extra process)))\n"
" (when a0-1\n"
" (let ((a1-1 (new 'stack-no-clear 'event-message-block)))\n"
" (set! (-> a1-1 from) pp)\n"
" (set! (-> a1-1 num-params) 0)\n"
" (set! (-> a1-1 message) arg1)\n"
" (set! s5-0 (or (send-event-function a0-1 a1-1) s5-0))\n"
" )\n"
" )\n"
" )\n"
" (set! s4-0 (entity-actor-lookup s4-0 'next-actor 0))\n"
" )\n"
" s5-0\n"
" )";
test_with_stack_structures(func, type, expected, "[[16, \"event-message-block\"]]");
}
TEST_F(FormRegressionTest, WeirdShortCircuit2) {
std::string func =
"sll r0, r0, 0\n"
"L62:\n"
" lwu v1, 8(a0)\n"
" beql s7, v1, L63\n"
" or v0, v1, r0\n"
" lwu v1, 8(a0)\n" // here's the case
" lwu v1, 20(v1)\n"
" lwu v0, 12(v1)\n"
"L63:\n"
" jr ra\n"
" daddu sp, sp, r0";
std::string type = "(function actor-link-info object)";
std::string expected = "(and (-> arg0 prev) (-> arg0 prev extra process))";
test_with_stack_structures(func, type, expected, "[[16, \"event-message-block\"]]");
}