Skip to content

Commit d8c26ad

Browse files
authored
Merge pull request #307 from TurboWarp/optimize-repeat-better
Improve repeat block analysis
2 parents 4187f55 + 8860e2d commit d8c26ad

File tree

4 files changed

+73
-6
lines changed

4 files changed

+73
-6
lines changed

src/compiler/iroptimizer.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,12 @@ class IROptimizer {
559559
break;
560560
case StackOpcode.CONTROL_WHILE:
561561
case StackOpcode.CONTROL_FOR:
562+
modified = this.analyzeInputs(inputs, state) || modified;
563+
modified = this.analyzeLoopedStack(inputs.do, state, stackBlock, true) || modified;
564+
break;
562565
case StackOpcode.CONTROL_REPEAT:
563566
modified = this.analyzeInputs(inputs, state) || modified;
564-
modified = this.analyzeLoopedStack(inputs.do, state, stackBlock) || modified;
567+
modified = this.analyzeLoopedStack(inputs.do, state, stackBlock, false) || modified;
565568
break;
566569
case StackOpcode.CONTROL_IF_ELSE: {
567570
modified = this.analyzeInputs(inputs, state) || modified;
@@ -642,20 +645,24 @@ class IROptimizer {
642645
* @param {IntermediateStack} stack
643646
* @param {TypeState} state
644647
* @param {IntermediateStackBlock} block
648+
* @param {boolean} willReevaluateInputs
645649
* @returns {boolean}
646650
* @private
647651
*/
648-
analyzeLoopedStack (stack, state, block) {
652+
analyzeLoopedStack (stack, state, block, willReevaluateInputs) {
653+
let modified = false;
654+
649655
if (block.yields && !this.ignoreYields) {
650-
let modified = state.clear();
656+
modified = state.clear();
657+
if (willReevaluateInputs) {
658+
modified = this.analyzeInputs(block.inputs, state) || modified;
659+
}
651660
block.entryState = state.clone();
652661
block.exitState = state.clone();
653-
modified = this.analyzeInputs(block.inputs, state) || modified;
654662
return this.analyzeStack(stack, state) || modified;
655663
}
656664

657665
let iterations = 0;
658-
let modified = false;
659666
let keepLooping;
660667
do {
661668
// If we are stuck in an apparent infinite loop, give up and assume the worst.
@@ -672,7 +679,10 @@ class IROptimizer {
672679
const newState = state.clone();
673680
modified = this.analyzeStack(stack, newState) || modified;
674681
modified = (keepLooping = state.or(newState)) || modified;
675-
modified = this.analyzeInputs(block.inputs, state) || modified;
682+
683+
if (willReevaluateInputs) {
684+
modified = this.analyzeInputs(block.inputs, state) || modified;
685+
}
676686
} while (keepLooping);
677687
block.entryState = state.clone();
678688
return modified;
Binary file not shown.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// TW Snapshot
2+
// Input SHA-256: 38075839898d1ba3d2556f350ff18438a205c5b6b3cb809d07d3f738bd37dad9
3+
4+
// Sprite1 script
5+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
6+
const b0 = runtime.getOpcodeFunction("looks_say");
7+
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
8+
return function* genXYZ () {
9+
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, "d", null);
10+
thread.procedures["Wa"]();
11+
if ((("" + b1.value).toLowerCase() === "bwah".toLowerCase())) {
12+
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "l", null);
13+
}
14+
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "k", null);
15+
retire(); return;
16+
}; })
17+
18+
// Sprite1 Wa
19+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
20+
const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
21+
const b1 = stage.variables["6h7bpiz0`;;x^G1B3(%["];
22+
return function funXYZ_a () {
23+
b0.value = b1.value.length;
24+
for (var a0 = b0.value; a0 > 0; a0--) {
25+
b0.value = "bwah";
26+
}
27+
return "";
28+
}; })
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// TW Snapshot
2+
// Input SHA-256: 38075839898d1ba3d2556f350ff18438a205c5b6b3cb809d07d3f738bd37dad9
3+
4+
// Sprite1 script
5+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
6+
const b0 = runtime.getOpcodeFunction("looks_say");
7+
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
8+
return function* genXYZ () {
9+
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, "d", null);
10+
yield* thread.procedures["Wa"]();
11+
if ((("" + b1.value).toLowerCase() === "bwah".toLowerCase())) {
12+
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "l", null);
13+
}
14+
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "k", null);
15+
retire(); return;
16+
}; })
17+
18+
// Sprite1 Wa
19+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
20+
const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
21+
const b1 = stage.variables["6h7bpiz0`;;x^G1B3(%["];
22+
return function* genXYZ_a () {
23+
b0.value = b1.value.length;
24+
for (var a0 = b0.value; a0 > 0; a0--) {
25+
b0.value = "bwah";
26+
if (isStuck()) yield;
27+
}
28+
return "";
29+
}; })

0 commit comments

Comments
 (0)