1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-09-11 02:55:10 +00:00

Always require a full optimization context when optimizing

This commit is contained in:
Karol Stasiak 2018-07-16 23:07:37 +02:00
parent f4ecc2512c
commit 21b086046c
4 changed files with 17 additions and 18 deletions

View File

@ -1,7 +1,7 @@
package millfork.assembly package millfork.assembly
import millfork.CompilationOptions import millfork.CompilationOptions
import millfork.env.NormalFunction import millfork.env.{NormalFunction, ThingInMemory}
import millfork.node.NiceFunctionProperty import millfork.node.NiceFunctionProperty
/** /**
@ -9,12 +9,11 @@ import millfork.node.NiceFunctionProperty
*/ */
case class OptimizationContext(options: CompilationOptions, case class OptimizationContext(options: CompilationOptions,
labelMap: Map[String, Int], labelMap: Map[String, Int],
zreg: Option[ThingInMemory],
niceFunctionProperties: Set[(NiceFunctionProperty, String)]) niceFunctionProperties: Set[(NiceFunctionProperty, String)])
trait AssemblyOptimization[T <: AbstractCode] { trait AssemblyOptimization[T <: AbstractCode] {
def name: String def name: String
def optimize(f: NormalFunction, code: List[T], context: OptimizationContext): List[T] = optimize(f, code, context.options) def optimize(f: NormalFunction, code: List[T], context: OptimizationContext): List[T]
def optimize(f: NormalFunction, code: List[T], options: CompilationOptions): List[T] = optimize(f, code, OptimizationContext(options, Map(), Set()))
} }

View File

@ -30,7 +30,7 @@ object FlowInfoRequirement extends Enumeration {
} }
trait AssemblyRuleSet{ trait AssemblyRuleSet{
def flatten: List[AssemblyRule] def flatten: Seq[AssemblyRule]
} }
class RuleBasedAssemblyOptimization(val name: String, val needsFlowInfo: FlowInfoRequirement.Value, val rules: AssemblyRuleSet*) extends AssemblyOptimization[ZLine]{ class RuleBasedAssemblyOptimization(val name: String, val needsFlowInfo: FlowInfoRequirement.Value, val rules: AssemblyRuleSet*) extends AssemblyOptimization[ZLine]{
@ -38,18 +38,18 @@ class RuleBasedAssemblyOptimization(val name: String, val needsFlowInfo: FlowInf
private val actualRules = rules.flatMap(_.flatten) private val actualRules = rules.flatMap(_.flatten)
actualRules.foreach(_.pattern.validate(needsFlowInfo)) actualRules.foreach(_.pattern.validate(needsFlowInfo))
override def optimize(f: NormalFunction, code: List[ZLine], options: CompilationOptions): List[ZLine] = { override def optimize(f: NormalFunction, code: List[ZLine], optimizationContext: OptimizationContext): List[ZLine] = {
val effectiveCode = code.map(a => a.copy(parameter = a.parameter.quickSimplify)) val effectiveCode = code.map(a => a.copy(parameter = a.parameter.quickSimplify))
val taggedCode = FlowAnalyzer.analyze(f, effectiveCode, options, needsFlowInfo) val taggedCode = FlowAnalyzer.analyze(f, effectiveCode, optimizationContext.options, needsFlowInfo)
optimizeImpl(f, taggedCode, options) optimizeImpl(f, taggedCode, optimizationContext)
} }
def optimizeImpl(f: NormalFunction, code: List[(FlowInfo, ZLine)], options: CompilationOptions): List[ZLine] = { def optimizeImpl(f: NormalFunction, code: List[(FlowInfo, ZLine)], optimizationContext: OptimizationContext): List[ZLine] = {
code match { code match {
case Nil => Nil case Nil => Nil
case head :: tail => case head :: tail =>
for ((rule, index) <- actualRules.zipWithIndex) { for ((rule, index) <- actualRules.zipWithIndex) {
val ctx = new AssemblyMatchingContext(options) val ctx = new AssemblyMatchingContext(optimizationContext.options)
rule.pattern.matchTo(ctx, code) match { rule.pattern.matchTo(ctx, code) match {
case Some(rest: List[(FlowInfo, ZLine)]) => case Some(rest: List[(FlowInfo, ZLine)]) =>
val matchedChunkToOptimize: List[ZLine] = code.take(code.length - rest.length).map(_._2) val matchedChunkToOptimize: List[ZLine] = code.take(code.length - rest.length).map(_._2)
@ -65,14 +65,14 @@ class RuleBasedAssemblyOptimization(val name: String, val needsFlowInfo: FlowInf
ErrorReporting.trace(" ↓") ErrorReporting.trace(" ↓")
optimizedChunk.filter(_.isPrintable).foreach(l => ErrorReporting.trace(l.toString)) optimizedChunk.filter(_.isPrintable).foreach(l => ErrorReporting.trace(l.toString))
if (needsFlowInfo != FlowInfoRequirement.NoRequirement) { if (needsFlowInfo != FlowInfoRequirement.NoRequirement) {
return optimizedChunk ++ optimizeImpl(f, rest, options) return optimizedChunk ++ optimizeImpl(f, rest, optimizationContext)
} else { } else {
return optimize(f, optimizedChunk ++ rest.map(_._2), options) return optimize(f, optimizedChunk ++ rest.map(_._2), optimizationContext)
} }
case None => () case None => ()
} }
} }
head._2 :: optimizeImpl(f, tail, options) head._2 :: optimizeImpl(f, tail, optimizationContext)
} }
} }
} }
@ -216,11 +216,11 @@ object HelperCheckers {
} }
} }
case class AssemblyRule(pattern: AssemblyPattern, result: (List[ZLine], AssemblyMatchingContext) => List[ZLine]) extends AssemblyRuleSet { case class AssemblyRule(pattern: AssemblyPattern, result: (List[ZLine], AssemblyMatchingContext) => List[ZLine]) extends AssemblyRuleSet {
override def flatten: List[AssemblyRule] = List(this) override def flatten: Seq[AssemblyRule] = List(this)
} }
case class MultipleAssemblyRules(list: List[AssemblyRuleSet]) extends AssemblyRuleSet { case class MultipleAssemblyRules(list: Seq[AssemblyRuleSet]) extends AssemblyRuleSet {
override def flatten: List[AssemblyRule] = list.flatMap(_.flatten) override def flatten: Seq[AssemblyRule] = list.flatMap(_.flatten)
} }
trait AssemblyPattern { trait AssemblyPattern {

View File

@ -474,7 +474,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
compiler)) compiler))
unoptimizedCodeSize += unoptimized.map(_.sizeInBytes).sum unoptimizedCodeSize += unoptimized.map(_.sizeInBytes).sum
val code = optimizations.foldLeft(unoptimized) { (c, opt) => val code = optimizations.foldLeft(unoptimized) { (c, opt) =>
opt.optimize(f, c, OptimizationContext(options, labelMap, niceFunctionProperties)) opt.optimize(f, c, OptimizationContext(options, labelMap, env.maybeGet[ThingInMemory]("__reg"), niceFunctionProperties))
} }
performFinalOptimizationPass(f, optimizations.nonEmpty, options, code) performFinalOptimizationPass(f, optimizations.nonEmpty, options, code)
} }

View File

@ -21,7 +21,7 @@ class MosAssembler(program: Program,
override def performFinalOptimizationPass(f: NormalFunction, actuallyOptimize: Boolean, options: CompilationOptions, code: List[AssemblyLine]):List[AssemblyLine] = { override def performFinalOptimizationPass(f: NormalFunction, actuallyOptimize: Boolean, options: CompilationOptions, code: List[AssemblyLine]):List[AssemblyLine] = {
val optimizationContext = OptimizationContext(options, Map(), Set()) val optimizationContext = OptimizationContext(options, Map(), f.environment.maybeGet[ThingInMemory]("__reg"), Set())
if (actuallyOptimize) { if (actuallyOptimize) {
val finalCode = if (options.flag(CompilationFlag.EmitHudsonOpcodes)) HudsonOptimizations.removeLoadZero(f, code, optimizationContext) else code val finalCode = if (options.flag(CompilationFlag.EmitHudsonOpcodes)) HudsonOptimizations.removeLoadZero(f, code, optimizationContext) else code
JumpShortening(f, JumpShortening(f, JumpFixing(f, finalCode, options), optimizationContext), optimizationContext) JumpShortening(f, JumpShortening(f, JumpFixing(f, finalCode, options), optimizationContext), optimizationContext)