1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Optimizing CMP/CPX/CPY/CPZ #0

This commit is contained in:
Karol Stasiak 2018-04-02 21:57:53 +02:00
parent 0ddf2f31c8
commit 146e598636
4 changed files with 31 additions and 0 deletions

View File

@ -118,6 +118,7 @@ object OptimizationPresets {
AlwaysGoodOptimizations.PointlessMathFromFlow,
AlwaysGoodOptimizations.PointlessMathFromFlow,
AlwaysGoodOptimizations.PointlessMathFromFlow,
AlwaysGoodOptimizations.OptimizeZeroComparisons,
AlwaysGoodOptimizations.SimplifiableCondition,
AlwaysGoodOptimizations.IncrementingIndexRegistersAfterTransfer,
AlwaysGoodOptimizations.MathOperationOnTwoIdenticalMemoryOperands,
@ -160,6 +161,7 @@ object OptimizationPresets {
AlwaysGoodOptimizations.NonetAddition,
AlwaysGoodOptimizations.NonetBitOp,
AlwaysGoodOptimizations.OperationsAroundShifting,
AlwaysGoodOptimizations.OptimizeZeroComparisons,
AlwaysGoodOptimizations.PoinlessFlagChange,
AlwaysGoodOptimizations.PointlessLoadAfterLoadOrStore,
AlwaysGoodOptimizations.PoinlessLoadBeforeAnotherLoad,

View File

@ -1600,6 +1600,14 @@ object AlwaysGoodOptimizations {
},
)
val OptimizeZeroComparisons = new RuleBasedAssemblyOptimization("Optimizing zero comparisons",
needsFlowInfo = FlowInfoRequirement.BothFlows,
(Elidable & HasSourceOfNZ(State.A) & HasOpcode(CMP) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_.init),
(Elidable & HasSourceOfNZ(State.X) & HasOpcode(CPX) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_.init),
(Elidable & HasSourceOfNZ(State.Y) & HasOpcode(CPY) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_.init),
(Elidable & HasSourceOfNZ(State.IZ) & HasOpcode(CPZ) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_.init),
)
private def remapZ2N(line: AssemblyLine) = line.opcode match {
case BNE => line.copy(opcode = BMI)
case BEQ => line.copy(opcode = BPL)

View File

@ -42,6 +42,11 @@ sealed trait Status[+T] {
case SingleStatus(x) => f(x)
case _ => AnyStatus
}
def exists(predicate: T => Boolean): Boolean = this match {
case AnyStatus | UnknownStatus => false
case SingleStatus(x) => predicate(x)
}
}
object SourceOfNZ {
@ -57,6 +62,14 @@ object SourceOfNZ {
}
case class SourceOfNZ(a: Boolean = false, aw: Boolean = false, x: Boolean = false, y: Boolean = false, iz: Boolean = false) {
def matches(state: State.Value): Boolean = state match {
case State.A => a
case State.X => x
case State.Y => y
case State.IZ => iz
case _ => throw new IllegalArgumentException
}
override def toString: String = {
val builder = new StringBuilder
if (a) builder += 'A'

View File

@ -556,6 +556,14 @@ case class HasSet(state: State.Value) extends AssemblyLinePattern {
flowInfo.hasSet(state)
}
case class HasSourceOfNZ(state: State.Value) extends AssemblyLinePattern {
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit =
FlowInfoRequirement.assertForward(needsFlowInfo)
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: AssemblyLine): Boolean =
flowInfo.statusBefore.src.exists(s => s.matches(state))
}
object HasAccu8 extends AssemblyLinePattern {
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit =
FlowInfoRequirement.assertForward(needsFlowInfo)