1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-04-11 23:37:15 +00:00

6502: Fix variable inlining

This commit is contained in:
Karol Stasiak 2018-12-28 01:17:23 +01:00
parent 95e37d63f1
commit e66e938469
2 changed files with 28 additions and 7 deletions

@ -90,7 +90,7 @@ object TwoVariablesToIndexRegistersOptimization extends AssemblyOptimization[Ass
}.map(_.name).toSet
val variablesWithLifetimes = localVariables.map(v =>
v.name -> VariableLifetime.apply(v.name, code)
v.name -> VariableLifetime.apply(v.name, code, expandToIncludeIndexing = true)
).toMap
val removeVariablesForReal = !options.flag(CompilationFlag.InternalCurrentlyOptimizingForMeasurement)
@ -196,7 +196,7 @@ object TwoVariablesToIndexRegistersOptimization extends AssemblyOptimization[Ass
case (AssemblyLine0(LDY, _, _), _) :: xs if "--" == vy =>
canBeInlined(vx, vy, loadedX, "-", xs)
case (AssemblyLine0(_, AbsoluteX, _), _) :: xs if loadedX == vx || vx == "--" =>
case (AssemblyLine0(_, AbsoluteX, _), _) :: xs if loadedX == vx || vx == "--" && loadedX == "-" =>
canBeInlined(vx, vy, loadedX, loadedY, xs)
case (AssemblyLine0(op, AbsoluteX, _), _) :: xs if loadedX == vy =>
@ -204,7 +204,7 @@ object TwoVariablesToIndexRegistersOptimization extends AssemblyOptimization[Ass
canBeInlined(vx, vy, loadedX, loadedY, xs)
} else fail(4)
case (AssemblyLine0(_, AbsoluteY, _), _) :: xs if loadedY == vy || vy == "--" =>
case (AssemblyLine0(_, AbsoluteY, _), _) :: xs if loadedY == vy || vy == "--" && loadedY == "-" =>
canBeInlined(vx, vy, loadedX, loadedY, xs)
case (AssemblyLine0(op, AbsoluteY, _), _) :: xs if loadedY == vx =>
@ -212,10 +212,10 @@ object TwoVariablesToIndexRegistersOptimization extends AssemblyOptimization[Ass
canBeInlined(vx, vy, loadedX, loadedY, xs)
} else fail(5)
case (AssemblyLine0(op, IndexedY | IndexedSY | ZeroPageY, _), _) :: xs if loadedY == vy || vy == "--" =>
case (AssemblyLine0(op, IndexedY | IndexedSY | ZeroPageY, _), _) :: xs if loadedY == vy || vy == "--" && loadedY == "-" =>
canBeInlined(vx, vy, loadedX, loadedY, xs)
case (AssemblyLine0(op, IndexedX | ZeroPageX | LongAbsoluteX, _), _) :: xs if loadedX == vx || vx == "--" =>
case (AssemblyLine0(op, IndexedX | ZeroPageX | LongAbsoluteX, _), _) :: xs if loadedX == vx || vx == "--" && loadedX == "-" =>
canBeInlined(vx, vy, loadedX, loadedY, xs)
case (AssemblyLine0(_, IndexedX | ZeroPageX | LongAbsoluteX | IndexedY | IndexedSY | ZeroPageY | AbsoluteX | AbsoluteY, _), _) :: xs =>

@ -1,6 +1,6 @@
package millfork.assembly.mos.opt
import millfork.assembly.mos.AssemblyLine
import millfork.assembly.mos.{AssemblyLine, OpcodeClasses}
import millfork.env._
import millfork.error.ConsoleLogger
@ -10,7 +10,7 @@ import millfork.error.ConsoleLogger
object VariableLifetime {
// This only works for non-stack variables.
def apply(variableName: String, code: List[AssemblyLine]): Range = {
def apply(variableName: String, code: List[AssemblyLine], expandToIncludeIndexing: Boolean = false): Range = {
val flags = code.map(_.parameter match {
case MemoryAddressConstant(MemoryVariable(n, _, _)) if n == variableName => true
case CompoundConstant(MathOperator.Plus, MemoryAddressConstant(MemoryVariable(n, _, _)), NumericConstant(_, 1)) if n == variableName => true
@ -41,6 +41,27 @@ object VariableLifetime {
}
}
if (expandToIncludeIndexing) {
import millfork.assembly.mos.Opcode._
import millfork.assembly.mos.AddrMode._
val linearChuckAfter = code.drop(max).takeWhile{ line => line.opcode match {
case LABEL | JSR | BSR | RTS | RTI => false
case op if OpcodeClasses.AllDirectJumps(op) => false
case _ => true
}}
val lastIndexing = linearChuckAfter.lastIndexWhere(line => line.addrMode match {
case IndexedY | IndexedX | IndexedSY => true
case AbsoluteY | AbsoluteX | LongAbsoluteX => true
case ZeroPageX | ZeroPageY => true
case _ => false
})
if (lastIndexing >= 0) {
max += lastIndexing + 1
}
}
// val log = new ConsoleLogger
// log.verbosity = 3
// log.trace("Lifetime for " + variableName)
// code.zipWithIndex.foreach {
// case (line, index) =>