diff --git a/src/main/scala/millfork/assembly/m6809/opt/FlowAnalyzer.scala b/src/main/scala/millfork/assembly/m6809/opt/FlowAnalyzer.scala index d749f915..c12bb531 100644 --- a/src/main/scala/millfork/assembly/m6809/opt/FlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/m6809/opt/FlowAnalyzer.scala @@ -52,7 +52,7 @@ object FlowAnalyzer { } val labelMap: () => Option[Map[String, Int]] = () => req match { case FlowInfoRequirement.NoRequirement => None - case _ => Some(code.flatMap(_.parameter.extractLabels).groupBy(identity).mapValues(_.size).view.force) + case _ => Some(code.filter(m => m.opcode != MOpcode.LABEL).flatMap(_.parameter.extractLabels).groupBy(identity).mapValues(_.size).view.force) } val holder = new FlowHolder(forwardFlow, reverseFlow) code.zipWithIndex.map{ case (line, i) => FlowInfo(holder, i, labelMap) -> line} diff --git a/src/main/scala/millfork/assembly/mos/opt/AlwaysGoodOptimizations.scala b/src/main/scala/millfork/assembly/mos/opt/AlwaysGoodOptimizations.scala index acb0327a..f75aa053 100644 --- a/src/main/scala/millfork/assembly/mos/opt/AlwaysGoodOptimizations.scala +++ b/src/main/scala/millfork/assembly/mos/opt/AlwaysGoodOptimizations.scala @@ -2065,7 +2065,7 @@ object AlwaysGoodOptimizations { val UnusedLabelRemoval = new RuleBasedAssemblyOptimization("Unused label removal", needsFlowInfo = FlowInfoRequirement.JustLabels, - (Elidable & HasOpcode(LABEL) & HasCallerCount(0)) ~~> (_ => Nil) + (Elidable & HasOpcode(LABEL) & HasCallerCount(0) & ParameterIsLocalLabel) ~~> (_ => Nil) ) val OperationsAroundShifting = new RuleBasedAssemblyOptimization("Operations around shifting", diff --git a/src/main/scala/millfork/assembly/mos/opt/FlowAnalyzer.scala b/src/main/scala/millfork/assembly/mos/opt/FlowAnalyzer.scala index 3e1d2375..375e9ef0 100644 --- a/src/main/scala/millfork/assembly/mos/opt/FlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/mos/opt/FlowAnalyzer.scala @@ -52,7 +52,7 @@ object FlowAnalyzer { } val labelMap: () => Option[Map[String, Int]] = () => req match { case FlowInfoRequirement.NoRequirement => None - case _ => Some(code.flatMap(_.parameter.extractLabels).groupBy(identity).mapValues(_.size).view.force) + case _ => Some(code.filter(m => m.opcode != Opcode.LABEL).flatMap(_.parameter.extractLabels).groupBy(identity).mapValues(_.size).view.force) } val holder = new FlowHolder(forwardFlow, reverseFlow) code.zipWithIndex.map{ case (line, i) => FlowInfo(holder, i, labelMap) -> line} diff --git a/src/main/scala/millfork/assembly/mos/opt/RuleBasedAssemblyOptimization.scala b/src/main/scala/millfork/assembly/mos/opt/RuleBasedAssemblyOptimization.scala index 5896066e..28336347 100644 --- a/src/main/scala/millfork/assembly/mos/opt/RuleBasedAssemblyOptimization.scala +++ b/src/main/scala/millfork/assembly/mos/opt/RuleBasedAssemblyOptimization.scala @@ -1575,6 +1575,16 @@ case class HasCallerCount(count: Int) extends AssemblyLinePattern { override def hitRate: Double = 0.31 } +object ParameterIsLocalLabel extends AssemblyLinePattern { + override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: AssemblyLine): Boolean = + line match { + case AssemblyLine0(Opcode.LABEL, _, MemoryAddressConstant(Label(l))) => l.startsWith(".") + case _ => false + } + + override def hitRate: Double = 0.056 +} + case class MatchElidableCopyOf(i: Int, firstLinePattern: AssemblyLinePattern, lastLinePattern: AssemblyLinePattern) extends AssemblyPattern { override def matchTo(ctx: AssemblyMatchingContext, code: List[(FlowInfo, AssemblyLine)]): Option[List[(FlowInfo, AssemblyLine)]] = { val pattern = ctx.get[List[AssemblyLine]](i) diff --git a/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala b/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala index da8cdcba..153b8903 100644 --- a/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala +++ b/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala @@ -1284,7 +1284,7 @@ object AlwaysGoodI80Optimizations { val UnusedLabelRemoval = new RuleBasedAssemblyOptimization("Unused label removal", needsFlowInfo = FlowInfoRequirement.JustLabels, - (Elidable & HasOpcode(LABEL) & HasCallerCount(0)) ~~> (_ => Nil) + (Elidable & HasOpcode(LABEL) & HasCallerCount(0) & ParameterIsLocalLabel) ~~> (_ => Nil) ) val BranchInPlaceRemoval = new RuleBasedAssemblyOptimization("Branch in place", diff --git a/src/main/scala/millfork/assembly/z80/opt/FlowAnalyzer.scala b/src/main/scala/millfork/assembly/z80/opt/FlowAnalyzer.scala index 53c10ab9..14358102 100644 --- a/src/main/scala/millfork/assembly/z80/opt/FlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/z80/opt/FlowAnalyzer.scala @@ -47,7 +47,7 @@ object FlowAnalyzer { } val labelMap: (() => Option[Map[String, Int]]) = () => req match { case FlowInfoRequirement.NoRequirement => None - case _ => Some(code.flatMap(_.parameter.extractLabels).groupBy(identity).mapValues(_.size).view.force) + case _ => Some(code.filter(m => m.opcode != ZOpcode.LABEL).flatMap(_.parameter.extractLabels).groupBy(identity).mapValues(_.size).view.force) } val holder = new FlowHolder(forwardFlow, reverseFlow) code.zipWithIndex.map{ case (line, i) => FlowInfo(holder, i, labelMap) -> line} diff --git a/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala b/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala index f74d7cbb..3283b960 100644 --- a/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala +++ b/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala @@ -1311,6 +1311,16 @@ case class HasCallerCount(count: Int) extends AssemblyLinePattern { override def hitRate: Double = 0.056 } +object ParameterIsLocalLabel extends AssemblyLinePattern { + override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = + line match { + case ZLine0(ZOpcode.LABEL, _, MemoryAddressConstant(Label(l))) => l.startsWith(".") + case _ => false + } + + override def hitRate: Double = 0.056 +} + case class MatchElidableCopyOf(i: Int, firstLinePattern: AssemblyLinePattern, lastLinePattern: AssemblyLinePattern) extends AssemblyPattern { override def matchTo(ctx: AssemblyMatchingContext, code: List[(FlowInfo, ZLine)]): Option[List[(FlowInfo, ZLine)]] = { val pattern = ctx.get[List[ZLine]](i)