From 28e53272b9050d27d79ea248621de0fbd9c75b8e Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Mon, 14 May 2018 02:18:33 +0200 Subject: [PATCH] Removal of pointless constant type; variable-to-register inlining fix --- .../opt/EmptyMemoryStoreRemoval.scala | 2 -- .../opt/LocalVariableReadOptimization.scala | 1 - ...SingleAssignmentVariableOptimization.scala | 1 - .../opt/VariableToRegisterOptimization.scala | 16 ++------- src/main/scala/millfork/env/Constant.scala | 36 +++++++------------ .../millfork/node/opt/UnusedFunctions.scala | 1 - .../node/opt/UnusedGlobalVariables.scala | 1 - .../node/opt/UnusedLocalVariables.scala | 1 - .../scala/millfork/output/Assembler.scala | 2 -- 9 files changed, 15 insertions(+), 46 deletions(-) diff --git a/src/main/scala/millfork/assembly/opt/EmptyMemoryStoreRemoval.scala b/src/main/scala/millfork/assembly/opt/EmptyMemoryStoreRemoval.scala index 033600ba..c46e2968 100644 --- a/src/main/scala/millfork/assembly/opt/EmptyMemoryStoreRemoval.scala +++ b/src/main/scala/millfork/assembly/opt/EmptyMemoryStoreRemoval.scala @@ -33,8 +33,6 @@ object EmptyMemoryStoreRemoval extends AssemblyOptimization { val variablesWithAddressesTaken = code.flatMap { case AssemblyLine(_, Immediate, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name) - case AssemblyLine(_, Immediate, HalfWordConstant(MemoryAddressConstant(th), _), _) => - Some(th.name) case _ => None }.toSet val allLocalVariables = f.environment.getAllLocalVariables diff --git a/src/main/scala/millfork/assembly/opt/LocalVariableReadOptimization.scala b/src/main/scala/millfork/assembly/opt/LocalVariableReadOptimization.scala index caa85799..df6fa4ce 100644 --- a/src/main/scala/millfork/assembly/opt/LocalVariableReadOptimization.scala +++ b/src/main/scala/millfork/assembly/opt/LocalVariableReadOptimization.scala @@ -28,7 +28,6 @@ object LocalVariableReadOptimization extends AssemblyOptimization { case _ => None }.toSet val variablesWithAddressesTaken = code.flatMap { - case AssemblyLine(_, _, HalfWordConstant(MemoryAddressConstant(th), _), _) => Some(th.name) case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name) case _ => None }.toSet diff --git a/src/main/scala/millfork/assembly/opt/SingleAssignmentVariableOptimization.scala b/src/main/scala/millfork/assembly/opt/SingleAssignmentVariableOptimization.scala index fd6b1d87..322d6412 100644 --- a/src/main/scala/millfork/assembly/opt/SingleAssignmentVariableOptimization.scala +++ b/src/main/scala/millfork/assembly/opt/SingleAssignmentVariableOptimization.scala @@ -45,7 +45,6 @@ object SingleAssignmentVariableOptimization extends AssemblyOptimization { case _ => None }.toSet val variablesWithAddressesTaken = code.flatMap { - case AssemblyLine(_, _, HalfWordConstant(MemoryAddressConstant(th), _), _) => Some(th.name) case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name) case _ => None }.toSet diff --git a/src/main/scala/millfork/assembly/opt/VariableToRegisterOptimization.scala b/src/main/scala/millfork/assembly/opt/VariableToRegisterOptimization.scala index daa6ab4b..11d9c198 100644 --- a/src/main/scala/millfork/assembly/opt/VariableToRegisterOptimization.scala +++ b/src/main/scala/millfork/assembly/opt/VariableToRegisterOptimization.scala @@ -115,7 +115,6 @@ object VariableToRegisterOptimization extends AssemblyOptimization { case _ => None }.toSet val variablesWithAddressesTaken = code.flatMap { - case AssemblyLine(_, _, HalfWordConstant(MemoryAddressConstant(th), _), _) => Some(th.name) case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name) case _ => None }.toSet @@ -328,10 +327,6 @@ object VariableToRegisterOptimization extends AssemblyOptimization { if th.name == vx || th.name == vy || th.name == vz => // if an address of a variable is used, then that variable cannot be assigned to a register None - case (AssemblyLine(_, Immediate, HalfWordConstant(MemoryAddressConstant(th), _), _), _) :: xs - if th.name == vx || th.name == vy || th.name == vz => - // if an address of a variable is used, then that variable cannot be assigned to a register - None case (AssemblyLine(_, AbsoluteX | AbsoluteY | LongAbsoluteX | ZeroPageX | ZeroPageY | @@ -585,11 +580,6 @@ object VariableToRegisterOptimization extends AssemblyOptimization { // if an address of a variable is used, then that variable cannot be assigned to a register None - case (AssemblyLine(_, Immediate, HalfWordConstant(MemoryAddressConstant(th), _), _),_) :: xs - if th.name == candidate => - // if an address of a variable is used, then that variable cannot be assigned to a register - None - case (AssemblyLine(_, AbsoluteX | AbsoluteY | ZeroPageX | ZeroPageY | IndexedY | IndexedX | IndexedZ | Indirect | AbsoluteIndexedX, MemoryAddressConstant(th), _),_) :: xs if th.name == candidate => // if a variable is used as an array or a pointer, then it cannot be assigned to a register @@ -773,7 +763,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization { case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs if opcodesCommutative(op) && th.name == va => - l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, zCandidate, aCandidate, features, xs) + clc :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, zCandidate, aCandidate, features, xs) case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs if opcodesCommutative(op) && th.name == vx => @@ -781,7 +771,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization { case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs if opcodesCommutative(op) && th.name == vx => - AssemblyLine.implied(TXA) :: l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, zCandidate, aCandidate, features, xs) + AssemblyLine.implied(TXA) :: clc :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, zCandidate, aCandidate, features, xs) case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs if opcodesCommutative(op) && th.name == vy => @@ -789,7 +779,7 @@ object VariableToRegisterOptimization extends AssemblyOptimization { case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs if opcodesCommutative(op) && th.name == vy => - AssemblyLine.implied(TYA) :: l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, zCandidate, aCandidate, features, xs) + AssemblyLine.implied(TYA) :: clc :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, zCandidate, aCandidate, features, xs) case (AssemblyLine(LDA | STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs if th.name == va => diff --git a/src/main/scala/millfork/env/Constant.scala b/src/main/scala/millfork/env/Constant.scala index 11fcad5d..bdc4fa56 100644 --- a/src/main/scala/millfork/env/Constant.scala +++ b/src/main/scala/millfork/env/Constant.scala @@ -41,12 +41,12 @@ sealed trait Constant { def loByte: Constant = { if (requiredSize == 1) return this - HalfWordConstant(this, hi = false) + SubbyteConstant(this, 0) } def hiByte: Constant = { if (requiredSize == 1) Constant.Zero - else HalfWordConstant(this, hi = true) + else SubbyteConstant(this, 1) } def subbyte(index: Int): Constant = { @@ -58,6 +58,14 @@ sealed trait Constant { } } + def subword(index: Int): Constant = { + if (requiredSize <= index) Constant.Zero + else { + // TODO: check if ok + CompoundConstant(MathOperator.Or, CompoundConstant(MathOperator.Shl, subbyte(index+1), NumericConstant(8, 1)), subbyte(0)).quickSimplify + } + } + def isLowestByteAlwaysEqual(i: Int) : Boolean = false def quickSimplify: Constant = this @@ -114,26 +122,6 @@ case class MemoryAddressConstant(var thing: ThingInMemory) extends Constant { override def isRelatedTo(v: Variable): Boolean = thing.name == v.name } -case class HalfWordConstant(base: Constant, hi: Boolean) extends Constant { - override def quickSimplify: Constant = { - val simplified = base.quickSimplify - simplified match { - case NumericConstant(x, size) => if (hi) { - if (size == 1) Constant.Zero else NumericConstant((x >> 8) & 0xff, 1) - } else { - NumericConstant(x & 0xff, 1) - } - case _ => HalfWordConstant(simplified, hi) - } - } - - override def requiredSize = 1 - - override def toString: String = (if (base.isInstanceOf[CompoundConstant]) s"($base)" else base) + (if (hi) ".hi" else ".lo") - - override def isRelatedTo(v: Variable): Boolean = base.isRelatedTo(v) -} - case class SubbyteConstant(base: Constant, index: Int) extends Constant { override def quickSimplify: Constant = { val simplified = base.quickSimplify @@ -186,7 +174,7 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co } else { CompoundConstant(MathOperator.Plus, a, rr - ll).quickSimplify } - case (CompoundConstant(MathOperator.Shl, HalfWordConstant(c1, true), NumericConstant(8, _)), HalfWordConstant(c2, false)) if operator == MathOperator.Or && c1 == c2 => c1 + case (CompoundConstant(MathOperator.Shl, SubbyteConstant(c1, 1), NumericConstant(8, _)), SubbyteConstant(c2, 0)) if operator == MathOperator.Or && c1 == c2 => c1 case (NumericConstant(lv, ls), NumericConstant(rv, rs)) => var size = ls max rs val value = operator match { @@ -271,7 +259,7 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co val That = that val MinusThat = -that this match { - case CompoundConstant(Plus, CompoundConstant(Shl, HalfWordConstant(c1, true), NumericConstant(8, _)), HalfWordConstant(c2, false)) if c1 == c2 => c1 + case CompoundConstant(Plus, CompoundConstant(Shl, SubbyteConstant(c1, 1), NumericConstant(8, _)), SubbyteConstant(c2, 0)) if c1 == c2 => c1 case CompoundConstant(Plus, NumericConstant(MinusThat, _), r) => r case CompoundConstant(Plus, l, NumericConstant(MinusThat, _)) => l case CompoundConstant(Plus, NumericConstant(x, _), r) => CompoundConstant(Plus, r, NumericConstant(x + that, minimumSize(x + that))) diff --git a/src/main/scala/millfork/node/opt/UnusedFunctions.scala b/src/main/scala/millfork/node/opt/UnusedFunctions.scala index 4be2c9d7..b262aa6b 100644 --- a/src/main/scala/millfork/node/opt/UnusedFunctions.scala +++ b/src/main/scala/millfork/node/opt/UnusedFunctions.scala @@ -41,7 +41,6 @@ object UnusedFunctions extends NodeOptimization { } def getAllCalledFunctions(c: Constant): List[String] = c match { - case HalfWordConstant(cc, _) => getAllCalledFunctions(cc) case SubbyteConstant(cc, _) => getAllCalledFunctions(cc) case CompoundConstant(_, l, r) => getAllCalledFunctions(l) ++ getAllCalledFunctions(r) case MemoryAddressConstant(th) => List( diff --git a/src/main/scala/millfork/node/opt/UnusedGlobalVariables.scala b/src/main/scala/millfork/node/opt/UnusedGlobalVariables.scala index 993facb1..e0787024 100644 --- a/src/main/scala/millfork/node/opt/UnusedGlobalVariables.scala +++ b/src/main/scala/millfork/node/opt/UnusedGlobalVariables.scala @@ -40,7 +40,6 @@ object UnusedGlobalVariables extends NodeOptimization { } def getAllReadVariables(c: Constant): List[String] = c match { - case HalfWordConstant(cc, _) => getAllReadVariables(cc) case SubbyteConstant(cc, _) => getAllReadVariables(cc) case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r) case MemoryAddressConstant(th) => List(th.name.takeWhile(_ != '.')) diff --git a/src/main/scala/millfork/node/opt/UnusedLocalVariables.scala b/src/main/scala/millfork/node/opt/UnusedLocalVariables.scala index 69533b38..e6434476 100644 --- a/src/main/scala/millfork/node/opt/UnusedLocalVariables.scala +++ b/src/main/scala/millfork/node/opt/UnusedLocalVariables.scala @@ -29,7 +29,6 @@ object UnusedLocalVariables extends NodeOptimization { } def getAllReadVariables(c: Constant): List[String] = c match { - case HalfWordConstant(cc, _) => getAllReadVariables(cc) case SubbyteConstant(cc, _) => getAllReadVariables(cc) case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r) case MemoryAddressConstant(th) => List( diff --git a/src/main/scala/millfork/output/Assembler.scala b/src/main/scala/millfork/output/Assembler.scala index 3be6d7f3..89bb1b3a 100644 --- a/src/main/scala/millfork/output/Assembler.scala +++ b/src/main/scala/millfork/output/Assembler.scala @@ -97,8 +97,6 @@ class Assembler(private val program: Program, private val rootEnv: Environment, case e: StackOverflowError => ErrorReporting.fatal("Stack overflow " + c) } - case HalfWordConstant(cc, true) => deepConstResolve(cc).>>>(8).&(0xff) - case HalfWordConstant(cc, false) => deepConstResolve(cc).&(0xff) case SubbyteConstant(cc, i) => deepConstResolve(cc).>>>(i * 8).&(0xff) case CompoundConstant(operator, lc, rc) => val l = deepConstResolve(lc)