mirror of
https://github.com/KarolS/millfork.git
synced 2025-02-08 15:30:50 +00:00
Optimization fixes (inlining to registers, function inlining, bit operations, DCP opcode)
This commit is contained in:
parent
b486436185
commit
64f72c8a1c
@ -90,7 +90,7 @@ object Main {
|
||||
if (options.flag(CompilationFlag.EmitCmosOpcodes)) CmosOptimizations.All else LaterOptimizations.Nmos,
|
||||
if (options.flag(CompilationFlag.DangerousOptimizations)) DangerousOptimizations.All else Nil,
|
||||
).flatten
|
||||
val goodCycle = List.fill(optLevel - 1)(OptimizationPresets.Good ++ extras).flatten
|
||||
val goodCycle = List.fill(optLevel - 1)(OptimizationPresets.Good).flatten
|
||||
val assemblyOptimizations = if (optLevel <= 0) Nil else if (optLevel >= 9) List(SuperOptimizer) else {
|
||||
goodCycle ++ OptimizationPresets.AssOpt ++ extras ++ goodCycle
|
||||
}
|
||||
|
@ -153,5 +153,6 @@ object OptimizationPresets {
|
||||
AlwaysGoodOptimizations.TailCallOptimization,
|
||||
AlwaysGoodOptimizations.UnusedCodeRemoval,
|
||||
AlwaysGoodOptimizations.UnusedLabelRemoval,
|
||||
VariableToRegisterOptimization,
|
||||
)
|
||||
}
|
||||
|
@ -921,16 +921,23 @@ object AlwaysGoodOptimizations {
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcodeIn(Set(ROL, ASL)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
||||
(Linear & DoesNotConcernMemoryAt(0, 1)).* ~
|
||||
(Linear & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
||||
(Elidable & HasOpcodeIn(Set(ROL, ASL)) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
||||
code.last :: code.drop(2).init
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
||||
(Linear & DoesNotConcernMemoryAt(0, 1)).* ~
|
||||
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
||||
(Linear & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
||||
(Elidable & HasOpcode(LSR) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
||||
code.last :: code.drop(2).init
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
||||
(Linear & Not(HasOpcode(LSR)) & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
||||
(Elidable & HasOpcode(LSR) & DoesNotConcernMemoryAt(0, 1)) ~
|
||||
(Elidable & HasOpcode(ROR) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
||||
code.init.last :: code.last :: code.drop(2).init.init
|
||||
},
|
||||
)
|
||||
|
||||
private def blockIsIdempotentWhenItComesToIndexRegisters(i: Int) = Where(ctx => {
|
||||
|
@ -32,5 +32,5 @@ object CmosOptimizations {
|
||||
(Elidable & HasX(0) & HasAddrMode(IndexedX) & HasOpcodeIn(SupportsZeroPageIndirect)) ~~> (code => code.map(_.copy(addrMode = ZeroPageIndirect))),
|
||||
)
|
||||
|
||||
val All: List[AssemblyOptimization] = List(ZeroStoreAsStz)
|
||||
val All: List[AssemblyOptimization] = List(OptimizeZeroIndex, ZeroStoreAsStz)
|
||||
}
|
||||
|
@ -259,15 +259,6 @@ object UndocumentedOptimizations {
|
||||
(Elidable & HasOpcode(DEC) & HasAddrMode(AbsoluteX) & DoesntMatterWhatItDoesWith(State.A, State.Y, State.X, State.C, State.Z, State.N, State.V)) ~~> { code =>
|
||||
List(code.head.copy(opcode = LDY), code.last.copy(opcode = DCP, addrMode = AbsoluteY))
|
||||
},
|
||||
(Elidable & HasOpcode(DEC) & Not(HasAddrMode(Immediate)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(LDA) & Not(HasAddrMode(Immediate)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(CMP) & MatchAddrMode(2) & MatchParameter(3) & DoesntMatterWhatItDoesWith(State.V, State.C, State.N, State.A)) ~~> { code =>
|
||||
List(code(2).copy(opcode = LDA), code(1).copy(opcode = DCP))
|
||||
},
|
||||
(Elidable & HasOpcode(DEC) & Not(HasAddrMode(Immediate)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(LDA) & Not(HasAddrMode(Immediate)) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.V, State.C, State.N, State.A)) ~~> { code =>
|
||||
List(AssemblyLine.immediate(LDA, 0), code(1).copy(opcode = DCP))
|
||||
},
|
||||
)
|
||||
|
||||
val UseIsc = new RuleBasedAssemblyOptimization("Using undocumented instruction ISC",
|
||||
|
@ -12,7 +12,7 @@ import scala.collection.mutable
|
||||
*/
|
||||
object InliningCalculator {
|
||||
|
||||
private val sizes = Seq(30, 30, 8, 6, 5, 5, 4)
|
||||
private val sizes = Seq(64, 64, 8, 6, 5, 5, 4)
|
||||
|
||||
def getPotentiallyInlineableFunctions(program: Program): Map[String, Int] = {
|
||||
val callCount = mutable.Map[String, Int]().withDefaultValue(0)
|
||||
|
@ -147,4 +147,26 @@ class BitPackingSuite extends FunSuite with Matchers {
|
||||
m.readByte(addr) should equal(0x5A)
|
||||
}
|
||||
}
|
||||
|
||||
test("Reverse word") {
|
||||
EmuBenchmarkRun("""
|
||||
| word output_addr @$C000
|
||||
| void main () {
|
||||
| byte i
|
||||
| word input
|
||||
| word output
|
||||
| output_addr = output.addr
|
||||
| input = $5AC1
|
||||
| output = 0
|
||||
| for i,0,paralleluntil,16 {
|
||||
| output <<= 1
|
||||
| output.lo |= input.lo & 1
|
||||
| input >>= 1
|
||||
| }
|
||||
| }
|
||||
""".stripMargin){m =>
|
||||
val addr = m.readWord(0xc000)
|
||||
m.readWord(addr) should equal(0x835A)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user