1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Removal of pointless constant type; variable-to-register inlining fix

This commit is contained in:
Karol Stasiak 2018-05-14 02:18:33 +02:00
parent 2f1faa12c2
commit 28e53272b9
9 changed files with 15 additions and 46 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 =>

View File

@ -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)))

View File

@ -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(

View File

@ -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(_ != '.'))

View File

@ -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(

View File

@ -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)