From c51c08ad5672d33c3e9a65ba53ba158eaf2780f9 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Wed, 5 May 2021 02:58:28 +0200 Subject: [PATCH] 6809: Fix and improve optimizations --- .../m6809/opt/AlwaysGoodMOptimizations.scala | 13 +++++++++++-- .../assembly/m6809/opt/ReverseFlowAnalyzer.scala | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/scala/millfork/assembly/m6809/opt/AlwaysGoodMOptimizations.scala b/src/main/scala/millfork/assembly/m6809/opt/AlwaysGoodMOptimizations.scala index 2d29944c..a5db6bcf 100644 --- a/src/main/scala/millfork/assembly/m6809/opt/AlwaysGoodMOptimizations.scala +++ b/src/main/scala/millfork/assembly/m6809/opt/AlwaysGoodMOptimizations.scala @@ -19,15 +19,23 @@ object AlwaysGoodMOptimizations { (Elidable & HasOpcodeIn(LDX, LEAX) & DoesntMatterWhatItDoesWith(MState.X, MState.NF, MState.ZF, MState.VF)) ~~> (_ => Nil), (Elidable & HasOpcodeIn(LDY, LEAY) & DoesntMatterWhatItDoesWith(MState.Y, MState.NF, MState.ZF, MState.VF)) ~~> (_ => Nil), (Elidable & HasOpcode(STB) & MatchAddrMode(0) & MatchParameter(1)) ~ - (Linear & Not(ChangesB) & DoesntChangeIndexingInAddrMode(0)).* ~ + (Linear & Not(ChangesB) & DoesntChangeIndexingInAddrMode(0) & DoesntChangeMemoryAt(0, 1)).* ~ (Elidable & HasOpcode(LDB) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(MState.NF, MState.ZF, MState.VF)) ~~> (_.init), (Elidable & HasOpcode(STD) & MatchAddrMode(0) & MatchParameter(1)) ~ - (Linear & Not(ChangesB) & DoesntChangeIndexingInAddrMode(0)).* ~ + (Linear & Not(ChangesB) & Not(ChangesA) & DoesntChangeIndexingInAddrMode(0) & DoesntChangeMemoryAt(0, 1)).* ~ (Elidable & HasOpcode(LDD) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(MState.NF, MState.ZF, MState.VF)) ~~> (_.init), ) + val PointlessCompare = new RuleBasedAssemblyOptimization("Pointless compare", + needsFlowInfo = FlowInfoRequirement.BackwardFlow, + (HasOpcodeIn(LDA, ANDA, ORA, EORA, ADDA, ADCA, SUBA, SBCA)) ~ DebugMatching ~ + (Elidable & HasOpcode(CMPA) & HasImmediate(0) & DoesntMatterWhatItDoesWith(MState.VF, MState.CF, MState.HF)) ~ DebugMatching ~~> {code => code.init}, + (HasOpcodeIn(LDB, ANDB, ORB, EORB, ADDB, ADCB, SUBB, SBCB)) ~ DebugMatching ~ + (Elidable & HasOpcode(CMPB) & HasImmediate(0) & DoesntMatterWhatItDoesWith(MState.VF, MState.CF, MState.HF)) ~ DebugMatching ~~> {code => code.init}, + ) + val SimplifiableZeroStore = new RuleBasedAssemblyOptimization("Simplifiable zero store", needsFlowInfo = FlowInfoRequirement.BothFlows, (Elidable & HasOpcode(LDA) & HasImmediate(0) & DoesntMatterWhatItDoesWith(MState.CF)) ~~> { @@ -149,6 +157,7 @@ object AlwaysGoodMOptimizations { val All: Seq[AssemblyOptimization[MLine]] = Seq( PointlessLoad, + PointlessCompare, PointlessRegisterTransfers, SimplifiableArithmetics, SimplifiableJumps, diff --git a/src/main/scala/millfork/assembly/m6809/opt/ReverseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/m6809/opt/ReverseFlowAnalyzer.scala index 9016f15e..3c98ede7 100644 --- a/src/main/scala/millfork/assembly/m6809/opt/ReverseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/m6809/opt/ReverseFlowAnalyzer.scala @@ -1,5 +1,6 @@ package millfork.assembly.m6809.opt +import jdk.jfr.BooleanFlag import millfork.assembly._ import millfork.assembly.m6809.{Absolute, MLine, MLine0, MOpcode, MState} import millfork.assembly.opt.FlowCache @@ -97,7 +98,7 @@ object ReverseFlowAnalyzer { private val finalImportance: CpuImportance = CpuImportance( a = Important, b = Important, x = Important, y = Important, u = Important, - cf = Important, vf = Important, hf = Important, zf = Important, nf = Important) + cf = Unimportant, vf = Unimportant, hf = Unimportant, zf = Unimportant, nf = Unimportant) //noinspection RedundantNewCaseClass def analyze(f: NormalFunction, code: List[MLine], optimizationContext: OptimizationContext): List[CpuImportance] = { @@ -108,9 +109,14 @@ object ReverseFlowAnalyzer { var changed = true changed = true + val actualFinalImportance = f.returnType match { + case FlagBooleanType(_, _, _) => finalImportance.copy(cf = Important, zf =Important, nf = Important, vf = Important) + case t if t.size == 1 => finalImportance.copy(a = Unimportant) + case _ => finalImportance + } while (changed) { changed = false - var currentImportance = finalImportance + var currentImportance = actualFinalImportance for (i <- codeArray.indices.reverse) { import millfork.assembly.m6809.MOpcode._ import millfork.node.M6809NiceFunctionProperty._ @@ -126,11 +132,13 @@ object ReverseFlowAnalyzer { case MLine0(LABEL, _, MemoryAddressConstant(Label(L))) => true case _ => false } - currentImportance = if (labelIndex < 0) finalImportance else importanceArray(labelIndex) ~ currentImportance + currentImportance = if (labelIndex < 0) actualFinalImportance else importanceArray(labelIndex) ~ currentImportance case _ => } currentLine match { + case MLine0(RTS, _, _) => + currentImportance = actualFinalImportance case MLine0(JSR | JMP, Absolute(false), MemoryAddressConstant(fun: FunctionInMemory)) => // this case has to be handled first, because the generic JSR importance handler is too conservative var result = importanceBeforeJsr @@ -173,7 +181,7 @@ object ReverseFlowAnalyzer { case MLine0(opcode, addrMode, _) => if (MOpcode.ChangesC(opcode)) currentImportance = currentImportance.copy(cf = Unimportant) if (MOpcode.ChangesN(opcode)) currentImportance = currentImportance.copy(nf = Unimportant) - if (MOpcode.ChangesZ(opcode)) currentImportance = currentImportance.copy(zf = Unimportant) + if (MOpcode.ChangesH(opcode)) currentImportance = currentImportance.copy(hf = Unimportant) if (MOpcode.ChangesZ(opcode)) currentImportance = currentImportance.copy(zf = Unimportant) if (MOpcode.ReadsC(opcode)) currentImportance = currentImportance.copy(cf = Important) if (MOpcode.ReadsH(opcode)) currentImportance = currentImportance.copy(hf = Important)