Skip to content

Commit

Permalink
Fixes #135: Optimization does not spot variable changed inside loop
Browse files Browse the repository at this point in the history
  • Loading branch information
cardillan committed Sep 10, 2024
1 parent 401d7c5 commit 298486e
Show file tree
Hide file tree
Showing 12 changed files with 5,712 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
*/
abstract class BaseOptimizer extends AbstractOptimizer {
protected static final boolean TRACE = false;
protected static final boolean DEBUG_PRINT = TRACE;
protected static final boolean DEBUG_PRINT = false;

protected int modifications = 0;
protected int insertions = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import info.teksol.mindcode.compiler.generator.CallGraph;
import info.teksol.mindcode.compiler.instructions.*;
import info.teksol.mindcode.compiler.optimization.DataFlowVariableStates.VariableStates;
import info.teksol.mindcode.compiler.optimization.DataFlowVariableStates.VariableValue;
import info.teksol.mindcode.compiler.optimization.OptimizationContext.LogicIterator;
import info.teksol.mindcode.logic.*;

Expand Down Expand Up @@ -168,7 +169,7 @@ private void replaceInstruction(LogicInstruction instruction) {
} else if (instruction instanceof SetInstruction set) {
// Specific optimization to streamline self-modifying statements in recursive calls
if (canEliminate(set, set.getResult()) && set.getValue().isTemporaryVariable()) {
VariableStates.VariableValue val = variableStates.findVariableValue(set.getValue());
VariableValue val = variableStates.findVariableValue(set.getValue());
if (val != null && val.isExpression() && val.getInstruction() instanceof OpInstruction op) {
if (op.inputArgumentsStream().anyMatch(set.getResult()::equals)) {
OpInstruction newInstruction = op.withContext(set.getAstContext()).withResult(set.getResult());
Expand Down Expand Up @@ -754,6 +755,8 @@ private VariableStates resolveLabel(VariableStates variableStates, LogicLabel la
return variableStates;
}

private int counter = 0;

/**
* Processes a single instruction.
*
Expand All @@ -768,7 +771,8 @@ private VariableStates processInstruction(VariableStates variableStates, LogicIn
Objects.requireNonNull(variableStates);
Objects.requireNonNull(instruction);

trace(() -> "Processing instruction #" + instructionIndex(instruction) +
counter++;
trace(() -> "*" + counter + " Processing instruction #" + instructionIndex(instruction) +
": " + LogicInstructionPrinter.toString(instructionProcessor, instruction));

switch (instruction) {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import info.teksol.mindcode.compiler.instructions.JumpInstruction;
import info.teksol.mindcode.compiler.instructions.OpInstruction;
import info.teksol.mindcode.compiler.optimization.DataFlowVariableStates.VariableStates;
import info.teksol.mindcode.compiler.optimization.DataFlowVariableStates.VariableStates.VariableValue;
import info.teksol.mindcode.compiler.optimization.DataFlowVariableStates.VariableValue;
import info.teksol.mindcode.logic.*;
import info.teksol.mindcode.processor.ExpressionEvaluator;
import info.teksol.mindcode.processor.MindustryValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,38 @@ void handlesNonConstantExpressions() {
createInstruction(JUMP, var(1000), "always")
);
}

@Test
void properlyInvalidatesExpressions() {
assertCompilesTo("""
a = rand(10) > 5
b = a > 5
c = b or a < 5
d = a
while true
if c
d += 1
c = b or d < 5
end
end
""",
createInstruction(OP, "rand", var(0), "10"),
createInstruction(OP, "greaterThan", "a", var(0), "5"),
createInstruction(OP, "greaterThan", "b", "a", "5"),
createInstruction(OP, "lessThan", var(3), "a", "5"),
createInstruction(OP, "or", "c", "b", var(3)),
createInstruction(SET, "d", "a"),
createInstruction(LABEL, var(1000)),
createInstruction(JUMP, var(1000), "equal", "c", "false"),
createInstruction(OP, "add", "d", "d", "1"),
createInstruction(OP, "lessThan", var(4), "d", "5"),
createInstruction(OP, "or", "c", "b", var(4)),
createInstruction(JUMP, var(1000), "always")


);
}
//</editor-fold>

//<editor-fold desc="Exit points">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
1 instructions eliminated by Dead Code Elimination (3 iterations).
16 instructions eliminated by Single Step Elimination (5 iterations).
1 instructions modified by If Expression Optimization (3 iterations).
40 instructions eliminated by Data Flow Optimization (3 passes, 13 iterations).
40 instructions eliminated by Data Flow Optimization (3 passes, 12 iterations).
2 instructions eliminated by Loop Optimization (3 iterations).
2 loops improved by Loop Optimization.
219 instructions added by Loop Unrolling (5 iterations).
Expand Down Expand Up @@ -1187,10 +1187,12 @@ Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 2 (-1
+ 299 read __tmp9 BITMAP __tmp3
300 op mod __tmp11 14 BITS
- * op shl __tmp12 1 __tmp11
- * op and __tmp8 __tmp9 __tmp12
+ 301 op shl __tmp12 1 __tmp4
302 op and __tmp8 __tmp9 __tmp12
+ 302 op and __tmp8 __tmp9 __tmp5
303 label __label120
304 jump __label121 equal __tmp8 false
305 set __tmp14 1

307 label __label121
308 print __tmp14
Expand All @@ -1207,26 +1209,14 @@ Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 2 (-1
325 label __label7
326 end

Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 3 (-2 instructions):
Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 3 (-3 instructions):

295 label __label118
296 set __tmp14 0
297 label __label119
- * op idiv __tmp10 14 BITS
298 read __tmp9 BITMAP __tmp3
- * op mod __tmp11 14 BITS
299 op shl __tmp12 1 __tmp4
- * op and __tmp8 __tmp9 __tmp12
+ 300 op and __tmp8 __tmp9 __tmp5
301 label __label120
302 jump __label121 equal __tmp8 false
303 set __tmp14 1

Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 4 (-1 instructions):

296 set __tmp14 0
297 label __label119
298 read __tmp9 BITMAP __tmp3
- * op shl __tmp12 1 __tmp4
299 op and __tmp8 __tmp9 __tmp5
300 label __label120
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ detector-00.mnd: 173 instructions, source CRC FE8119939
factory-monitor-00.mnd: 357 instructions, source CRC 735D793DE9291346, compiled CRC BD9B6E1EB255B21C
factory-monitor-silicon-00.mnd: 291 instructions, source CRC A359A3FF5FB80033, compiled CRC E7389555BDC3125C
factory-monitor-surge-alloy-00.mnd: 194 instructions, source CRC FB39BBCB30FDEA11, compiled CRC E93022DEEB3840D3
impact-reactor-logic-00.mnd: 882 instructions, source CRC 5FE7F84A717D715F, compiled CRC 764C0E3D998F1DC1
instant-overdrive-dome-00.mnd: 633 instructions, source CRC A1AE234B22C7A682, compiled CRC 26AAE5623D20AF94
item-counter-00.mnd: 99 instructions, source CRC 4D90F2B3A3A52A57, compiled CRC 102983144F395C25
item-counter-micro-00.mnd: 143 instructions, source CRC 38F77F7CF7606263, compiled CRC 390700627A884E47
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
breakout-00.mnd: : parse: 400 ms, compile: 0 ms, optimize: 0 ms
breakout-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
detector-00.mnd: : parse: 0 ms, compile: 0 ms, optimize: 0 ms
factory-monitor-00.mnd: : parse: 400 ms, compile: 0 ms, optimize: 200 ms
factory-monitor-silicon-00.mnd: : parse: 400 ms, compile: 0 ms, optimize: 0 ms
factory-monitor-silicon-00.mnd: : parse: 400 ms, compile: 0 ms, optimize: 200 ms
factory-monitor-surge-alloy-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
impact-reactor-logic-00.mnd: : parse: 400 ms, compile: 0 ms, optimize: 800 ms
instant-overdrive-dome-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 200 ms
item-counter-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
item-counter-micro-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
Expand All @@ -14,12 +15,12 @@ level-meter-00.mnd: : parse: 200 ms, compile:
mass-driver-monitor-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
mass-driver-monitor-surge-alloy-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
reactor-control-00.mnd: : parse: 1,200 ms, compile: 0 ms, optimize: 200 ms
reactor-control-battery-level-00.mnd: : parse: 400 ms, compile: 0 ms, optimize: 200 ms
reactor-control-battery-level-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 200 ms
regulator-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
remote-vault-00.mnd: : parse: 0 ms, compile: 0 ms, optimize: 0 ms
storage-display-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 200 ms
storage-display-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 400 ms
unit-housekeeping-00.mnd: : parse: 0 ms, compile: 0 ms, optimize: 0 ms
unit-speed-00.mnd: : parse: 0 ms, compile: 0 ms, optimize: 0 ms
unit-transport-00.mnd: : parse: 600 ms, compile: 0 ms, optimize: 400 ms
unit-transport-00.mnd: : parse: 600 ms, compile: 0 ms, optimize: 600 ms
unit-transport-flow-rate-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
unit-transport-single-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 0 ms
unit-transport-single-00.mnd: : parse: 200 ms, compile: 0 ms, optimize: 200 ms
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
15 instructions eliminated by Single Step Elimination (2 passes, 6 iterations).
1 instructions modified by Expression Optimization (3 iterations).
8 instructions eliminated by If Expression Optimization (3 iterations).
16 instructions eliminated by Data Flow Optimization (3 passes, 12 iterations).
16 instructions eliminated by Data Flow Optimization (3 passes, 11 iterations).
4 instructions added by Loop Optimization (3 iterations).
4 loops improved by Loop Optimization.
11 instructions eliminated by Jump Straightening (2 passes, 4 iterations).
Expand Down Expand Up @@ -1476,30 +1476,20 @@ Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 1:
174 op equal __tmp0 DISPLAY null
175 op equal __tmp1 TYPE null
- * op or __tmp2 __tmp0 __tmp1
- * jump __label86 notEqual __tmp2 false
+ 176 op or __tmp2 __tmp25 __tmp26
177 jump __label86 notEqual __tmp2 false
+ 177 jump __label86 notEqual __tmp27 false
178 label __label2
179 sensor __tmp29 DISPLAY @type
180 jump __label29 notEqual __tmp29 @logic-display

Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 2 (-2 instructions):
Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 2 (-3 instructions):

171 label __label28
172 printflush MESSAGE
173 label __label1
- * op equal __tmp0 DISPLAY null
- * op equal __tmp1 TYPE null
174 op or __tmp2 __tmp25 __tmp26
- * jump __label86 notEqual __tmp2 false
+ 175 jump __label86 notEqual __tmp27 false
176 label __label2
177 sensor __tmp29 DISPLAY @type
178 jump __label29 notEqual __tmp29 @logic-display

Modifications by Iterated phase, Data Flow Optimization, pass 1, iteration 3 (-1 instructions):

171 label __label28
172 printflush MESSAGE
173 label __label1
- * op or __tmp2 __tmp25 __tmp26
174 jump __label86 notEqual __tmp27 false
175 label __label2
Expand Down
Loading

0 comments on commit 298486e

Please sign in to comment.