mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-23 23:30:22 +00:00
Optimize loads of the same value that was just checked to be in a register
This commit is contained in:
parent
3b7ceb3900
commit
7be5b14a7d
@ -554,6 +554,43 @@ object LaterOptimizations {
|
||||
(Elidable & HasOpcode(STA) & HasAddrModeIn(Absolute, ZeroPage) & DoesntMatterWhatItDoesWith(State.A)) ~~>{ code =>
|
||||
List(code.head, code.last.copy(opcode = STY))
|
||||
},
|
||||
|
||||
(Elidable & HasOpcode(CMP) & MatchParameter(0) & MatchAddrMode(1)) ~
|
||||
(Elidable & HasOpcode(BNE)) ~
|
||||
(Elidable & HasOpcode(LDA) & MatchParameter(0) & MatchAddrMode(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~>{ code =>
|
||||
code.init
|
||||
},
|
||||
(Elidable & HasOpcode(CPX) & MatchParameter(0) & MatchAddrMode(1)) ~
|
||||
(Elidable & HasOpcode(BNE)) ~
|
||||
(Elidable & HasOpcode(LDX) & MatchParameter(0) & MatchAddrMode(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~>{ code =>
|
||||
code.init
|
||||
},
|
||||
(Elidable & HasOpcode(CPY) & MatchParameter(0) & MatchAddrMode(1)) ~
|
||||
(Elidable & HasOpcode(BNE)) ~
|
||||
(Elidable & HasOpcode(LDY) & MatchParameter(0) & MatchAddrMode(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~>{ code =>
|
||||
code.init
|
||||
},
|
||||
|
||||
(Elidable & HasOpcode(CMP) & MatchParameter(0) & MatchAddrMode(1)) ~
|
||||
(Elidable & HasOpcode(BNE)) ~
|
||||
(Elidable & HasOpcode(LDX) & MatchParameter(0) & MatchAddrMode(1)) ~~>{ code =>
|
||||
code.init :+ AssemblyLine.implied(TAX).pos(code.last.source)
|
||||
},
|
||||
(Elidable & HasOpcode(CMP) & MatchParameter(0) & MatchAddrMode(1)) ~
|
||||
(Elidable & HasOpcode(BNE) & IsNotALabelUsedManyTimes) ~
|
||||
(Elidable & HasOpcode(LDY) & MatchParameter(0) & MatchAddrMode(1)) ~~>{ code =>
|
||||
code.init :+ AssemblyLine.implied(TAY).pos(code.last.source)
|
||||
},
|
||||
(Elidable & HasOpcode(CPX) & MatchParameter(0) & MatchAddrMode(1)) ~
|
||||
(Elidable & HasOpcode(BNE)) ~
|
||||
(Elidable & HasOpcode(LDA) & MatchParameter(0) & MatchAddrMode(1)) ~~>{ code =>
|
||||
code.init :+ AssemblyLine.implied(TXA).pos(code.last.source)
|
||||
},
|
||||
(Elidable & HasOpcode(CPY) & MatchParameter(0) & MatchAddrMode(1)) ~
|
||||
(Elidable & HasOpcode(BNE)) ~
|
||||
(Elidable & HasOpcode(LDA) & MatchParameter(0) & MatchAddrMode(1)) ~~>{ code =>
|
||||
code.init :+ AssemblyLine.implied(TYA).pos(code.last.source)
|
||||
},
|
||||
)
|
||||
|
||||
val DontUseIndexRegisters = new RuleBasedAssemblyOptimization("Don't use index registers unnecessarily",
|
||||
|
@ -1625,3 +1625,15 @@ case object IsNotALabelUsedManyTimes extends AssemblyLinePattern {
|
||||
|
||||
override def hitRate: Double = 0.92 // ?
|
||||
}
|
||||
|
||||
case object ParameterIsLabel extends AssemblyLinePattern {
|
||||
|
||||
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit = FlowInfoRequirement.assertLabels(needsFlowInfo)
|
||||
|
||||
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: AssemblyLine): Boolean = line.parameter match {
|
||||
case MemoryAddressConstant(Label(l)) => true
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def hitRate: Double = 0.09 // ?
|
||||
}
|
||||
|
@ -324,6 +324,16 @@ object AlwaysGoodI80Optimizations {
|
||||
//69
|
||||
(HasOpcode(LD) & MatchSourceRealRegister(2) & MatchTargetRealRegister(3)) ~
|
||||
(Elidable & HasOpcode(LD) & MatchSourceRealRegister(3) & MatchTargetRealRegister(2)) ~~> (_.init),
|
||||
|
||||
// 70
|
||||
(HasOpcode(CP) & Match8BitImmediate(1)) ~
|
||||
(HasOpcodeIn(Set(JP, JR, RET)) & HasRegisters(IfFlagClear(ZFlag.Z))) ~
|
||||
(Elidable & HasOpcode(LD) & HasTargetRegister(A) & Match8BitImmediate(1)) ~~> (_.init),
|
||||
|
||||
// 71
|
||||
(HasOpcode(CP) & MatchSoleRegisterAndOffset(1)) ~
|
||||
(HasOpcodeIn(Set(JP, JR, RET)) & HasRegisters(IfFlagClear(ZFlag.Z))) ~
|
||||
(Elidable & HasOpcode(LD) & HasTargetRegister(A) & MatchSourceRegisterAndOffset(1)) ~~> (_.init),
|
||||
)
|
||||
|
||||
val PointlessStackStashing = new RuleBasedAssemblyOptimization("Pointless stack stashing",
|
||||
|
@ -584,6 +584,15 @@ case class MatchSourceRegisterAndOffset(i: Int) extends AssemblyLinePattern {
|
||||
override def hitRate: Double = 0.931
|
||||
}
|
||||
|
||||
case class HasTargetRegister(i: ZRegister.Value) extends AssemblyLinePattern {
|
||||
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean =
|
||||
line.registers match {
|
||||
case TwoRegisters(t, _) => t == i
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def hitRate: Double = 0.879
|
||||
}
|
||||
case class MatchTargetRegisterAndOffset(i: Int) extends AssemblyLinePattern {
|
||||
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean =
|
||||
line.registers match {
|
||||
@ -1323,4 +1332,16 @@ case object IsNotALabelUsedManyTimes extends AssemblyLinePattern {
|
||||
}
|
||||
|
||||
override def hitRate: Double = 0.999
|
||||
}
|
||||
}
|
||||
|
||||
case object ParameterIsLabel extends AssemblyLinePattern {
|
||||
|
||||
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit = FlowInfoRequirement.assertLabels(needsFlowInfo)
|
||||
|
||||
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = line.parameter match {
|
||||
case MemoryAddressConstant(Label(l)) => true
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def hitRate: Double = 0.09 // ?
|
||||
}
|
||||
|
@ -747,4 +747,25 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
|
||||
EmuOptimizedZ80Run(c).readByte(0xc000) should equal(13)
|
||||
EmuOptimizedIntel8080Run(c).readByte(0xc000) should equal(13)
|
||||
}
|
||||
|
||||
test("Optimize load after test") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Intel8080)(
|
||||
"""
|
||||
| byte output @ $c000
|
||||
| void main() {
|
||||
| f(2)
|
||||
| }
|
||||
| noinline void f(byte i) {
|
||||
| if (i == 2) {
|
||||
| g(2)
|
||||
| }
|
||||
| }
|
||||
| noinline void g(byte i) {
|
||||
| output = i
|
||||
| }
|
||||
""".stripMargin
|
||||
) { m =>
|
||||
m.readByte(0xc000) should equal(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user