1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-01-11 12:29:46 +00:00

Optimize commutative in-place modifications using arrays and pointers

This commit is contained in:
Karol Stasiak 2020-03-17 12:20:55 +01:00
parent 128dabba3f
commit 7939b0f2c1
3 changed files with 43 additions and 0 deletions

View File

@ -154,6 +154,7 @@ object OptimizationPresets {
AlwaysGoodOptimizations.PointlessMathFromFlow,
AlwaysGoodOptimizations.PointlessMathFromFlow,
AlwaysGoodOptimizations.PointlessMathFromFlow,
LaterOptimizations.CommutativeInPlaceModifications,
AlwaysGoodOptimizations.LoadingOfJustWrittenValue,
AlwaysGoodOptimizations.PointlessStackStore,
AlwaysGoodOptimizations.OptimizeZeroComparisons,

View File

@ -544,7 +544,23 @@ object LaterOptimizations {
)
val CommutativeInPlaceModifications = new RuleBasedAssemblyOptimization("Commutative in-place modifications",
needsFlowInfo = FlowInfoRequirement.NoRequirement,
(Elidable & HasOpcode(LDY) & HasAddrModeIn(Immediate, Absolute, ZeroPage, LongAbsolute, AbsoluteX, ZeroPageX) & MatchAddrMode(0) & MatchParameter(1)) ~
(Elidable & HasOpcode(LDA) & HasAddrModeIn(AbsoluteY, IndexedY, LongIndexedY)) ~
(Elidable & HasOpcode(LDY) & HasAddrModeIn(Immediate, Absolute, ZeroPage, LongAbsolute, AbsoluteX, ZeroPageX)) ~
(Elidable & HasOpcodeIn(ORA, EOR, AND) & HasAddrModeIn(AbsoluteY, IndexedY, LongIndexedY)) ~
(Elidable & HasOpcode(LDY) & HasAddrModeIn(Immediate, Absolute, ZeroPage, LongAbsolute, AbsoluteX, ZeroPageX) & MatchAddrMode(0) & MatchParameter(1)) ~
(HasOpcodeIn(INY, DEY)).* ~
(HasOpcode(STA) & HasAddrModeIn(AbsoluteY, IndexedY, LongIndexedY)) ~~> { code =>
List(code(2), code(3).copy(opcode = LDA), code(5), code(1).copy(opcode = code(3).opcode)) ++ code.drop(5)
},
)
val All = List(
CommutativeInPlaceModifications,
DontUseIndexRegisters,
DoubleLoadToDifferentRegisters,
DoubleLoadToTheSameRegister,

View File

@ -845,4 +845,30 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
}
EmuUndocumentedRun(code)
}
test("Optimize commutative in-place modifications using small arrays") {
val code =
"""
|
|array output [4] @$c000
|
|void main() {
| f($c000, 1, $c000, 2)
| g(1, 2)
|}
|
|noinline void f(pointer p1, byte i1, pointer p2, byte i2) {
| p1[i1] ^= p2[i2]
|}
|
|noinline void g(byte i1, byte i2) {
| output[i1] ^= output[i2]
|}
|
|""".stripMargin
EmuCrossPlatformBenchmarkRun(Cpu.Mos)(code) { m =>
}
}
}