From 23b4b110a6459d83c403e9e5d6a05545065494d6 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Mon, 24 Jun 2019 15:17:05 +0200 Subject: [PATCH] 8080: optimize more pointless loads --- .../z80/opt/AlwaysGoodI80Optimizations.scala | 4 +++ .../opt/RuleBasedAssemblyOptimization.scala | 27 +++++++++++++++++++ src/main/scala/millfork/node/Node.scala | 2 ++ 3 files changed, 33 insertions(+) diff --git a/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala b/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala index cc7cf511..5301b72e 100644 --- a/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala +++ b/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala @@ -292,6 +292,10 @@ object AlwaysGoodI80Optimizations { ctx.get[List[ZLine]](2) :+ ZLine.register(DEC_16, HL) }, + // 67 + (HasOpcode(LD) & MatchSourceRealRegister(0) & MatchTargetRealRegister(1)) ~ + (Linear & Not(ChangesMatchedRegister(0)) & Not(ChangesMatchedRegister(1))).* ~ + (Elidable & HasOpcode(LD) & MatchSourceRealRegister(1) & MatchTargetRealRegister(0)) ~~> (_.init), ) val PointlessStackStashing = new RuleBasedAssemblyOptimization("Pointless stack stashing", diff --git a/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala b/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala index 1c7abada..fa4cae3f 100644 --- a/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala +++ b/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala @@ -573,6 +573,26 @@ case class MatchTargetRegisterAndOffset(i: Int) extends AssemblyLinePattern { override def hitRate: Double = 0.879 } +case class MatchSourceRealRegister(i: Int) extends AssemblyLinePattern { + override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = + line.registers match { + case TwoRegisters(_, s) if ZRegister.main7Registers(s) => ctx.addObject(i, s) + case _ => false + } + + override def hitRate: Double = 0.931 +} + +case class MatchTargetRealRegister(i: Int) extends AssemblyLinePattern { + override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = + line.registers match { + case TwoRegisters(t, _) if ZRegister.main7Registers(t) => ctx.addObject(i, t) + case _ => false + } + + override def hitRate: Double = 0.879 +} + case class MatchSoleRegisterAndOffset(i: Int) extends AssemblyLinePattern { override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = line.registers match { @@ -924,6 +944,13 @@ case class Changes(register: ZRegister.Value) extends TrivialAssemblyLinePattern override def hitRate: Double = 0.212 } +case class ChangesMatchedRegister(register: Int) extends AssemblyLinePattern { + + override def hitRate: Double = 0.212 // ? + + override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = line.changesRegister(ctx.get[ZRegister.Value](register)) +} + case class Concerns(register: ZRegister.Value) extends TrivialAssemblyLinePattern { override def apply(line: ZLine): Boolean = line.readsRegister(register) || line.changesRegister(register) diff --git a/src/main/scala/millfork/node/Node.scala b/src/main/scala/millfork/node/Node.scala index 89b940cd..4399fc70 100644 --- a/src/main/scala/millfork/node/Node.scala +++ b/src/main/scala/millfork/node/Node.scala @@ -174,6 +174,8 @@ object ZRegister extends Enumeration { case 1 => MEM_ABS_8 case 2 => MEM_ABS_16 } + + val main7Registers: Set[ZRegister.Value] = Set[ZRegister.Value](ZRegister.A, ZRegister.B, ZRegister.C, ZRegister.D, ZRegister.D, ZRegister.E, ZRegister.H, ZRegister.L) } //case class Indexing(child: Expression, register: Register.Value) extends Expression