mirror of
https://github.com/KarolS/millfork.git
synced 2024-09-10 11:54:30 +00:00
Removal of pointless constant type; variable-to-register inlining fix
This commit is contained in:
parent
2f1faa12c2
commit
28e53272b9
@ -33,8 +33,6 @@ object EmptyMemoryStoreRemoval extends AssemblyOptimization {
|
|||||||
val variablesWithAddressesTaken = code.flatMap {
|
val variablesWithAddressesTaken = code.flatMap {
|
||||||
case AssemblyLine(_, Immediate, SubbyteConstant(MemoryAddressConstant(th), _), _) =>
|
case AssemblyLine(_, Immediate, SubbyteConstant(MemoryAddressConstant(th), _), _) =>
|
||||||
Some(th.name)
|
Some(th.name)
|
||||||
case AssemblyLine(_, Immediate, HalfWordConstant(MemoryAddressConstant(th), _), _) =>
|
|
||||||
Some(th.name)
|
|
||||||
case _ => None
|
case _ => None
|
||||||
}.toSet
|
}.toSet
|
||||||
val allLocalVariables = f.environment.getAllLocalVariables
|
val allLocalVariables = f.environment.getAllLocalVariables
|
||||||
|
@ -28,7 +28,6 @@ object LocalVariableReadOptimization extends AssemblyOptimization {
|
|||||||
case _ => None
|
case _ => None
|
||||||
}.toSet
|
}.toSet
|
||||||
val variablesWithAddressesTaken = code.flatMap {
|
val variablesWithAddressesTaken = code.flatMap {
|
||||||
case AssemblyLine(_, _, HalfWordConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
|
||||||
case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
||||||
case _ => None
|
case _ => None
|
||||||
}.toSet
|
}.toSet
|
||||||
|
@ -45,7 +45,6 @@ object SingleAssignmentVariableOptimization extends AssemblyOptimization {
|
|||||||
case _ => None
|
case _ => None
|
||||||
}.toSet
|
}.toSet
|
||||||
val variablesWithAddressesTaken = code.flatMap {
|
val variablesWithAddressesTaken = code.flatMap {
|
||||||
case AssemblyLine(_, _, HalfWordConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
|
||||||
case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
||||||
case _ => None
|
case _ => None
|
||||||
}.toSet
|
}.toSet
|
||||||
|
@ -115,7 +115,6 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
case _ => None
|
case _ => None
|
||||||
}.toSet
|
}.toSet
|
||||||
val variablesWithAddressesTaken = code.flatMap {
|
val variablesWithAddressesTaken = code.flatMap {
|
||||||
case AssemblyLine(_, _, HalfWordConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
|
||||||
case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
case AssemblyLine(_, _, SubbyteConstant(MemoryAddressConstant(th), _), _) => Some(th.name)
|
||||||
case _ => None
|
case _ => None
|
||||||
}.toSet
|
}.toSet
|
||||||
@ -328,10 +327,6 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
if th.name == vx || th.name == vy || th.name == vz =>
|
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
|
// if an address of a variable is used, then that variable cannot be assigned to a register
|
||||||
None
|
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 |
|
case (AssemblyLine(_, AbsoluteX | AbsoluteY | LongAbsoluteX |
|
||||||
ZeroPageX | ZeroPageY |
|
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
|
// if an address of a variable is used, then that variable cannot be assigned to a register
|
||||||
None
|
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
|
case (AssemblyLine(_, AbsoluteX | AbsoluteY | ZeroPageX | ZeroPageY | IndexedY | IndexedX | IndexedZ | Indirect | AbsoluteIndexedX, MemoryAddressConstant(th), _),_) :: xs
|
||||||
if th.name == candidate =>
|
if th.name == candidate =>
|
||||||
// if a variable is used as an array or a pointer, then it cannot be assigned to a register
|
// 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
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == va =>
|
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
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == vx =>
|
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
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == vx =>
|
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
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == vy =>
|
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
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
if opcodesCommutative(op) && th.name == vy =>
|
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
|
case (AssemblyLine(LDA | STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
|
36
src/main/scala/millfork/env/Constant.scala
vendored
36
src/main/scala/millfork/env/Constant.scala
vendored
@ -41,12 +41,12 @@ sealed trait Constant {
|
|||||||
|
|
||||||
def loByte: Constant = {
|
def loByte: Constant = {
|
||||||
if (requiredSize == 1) return this
|
if (requiredSize == 1) return this
|
||||||
HalfWordConstant(this, hi = false)
|
SubbyteConstant(this, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
def hiByte: Constant = {
|
def hiByte: Constant = {
|
||||||
if (requiredSize == 1) Constant.Zero
|
if (requiredSize == 1) Constant.Zero
|
||||||
else HalfWordConstant(this, hi = true)
|
else SubbyteConstant(this, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
def subbyte(index: Int): Constant = {
|
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 isLowestByteAlwaysEqual(i: Int) : Boolean = false
|
||||||
|
|
||||||
def quickSimplify: Constant = this
|
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
|
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 {
|
case class SubbyteConstant(base: Constant, index: Int) extends Constant {
|
||||||
override def quickSimplify: Constant = {
|
override def quickSimplify: Constant = {
|
||||||
val simplified = base.quickSimplify
|
val simplified = base.quickSimplify
|
||||||
@ -186,7 +174,7 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
|
|||||||
} else {
|
} else {
|
||||||
CompoundConstant(MathOperator.Plus, a, rr - ll).quickSimplify
|
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)) =>
|
case (NumericConstant(lv, ls), NumericConstant(rv, rs)) =>
|
||||||
var size = ls max rs
|
var size = ls max rs
|
||||||
val value = operator match {
|
val value = operator match {
|
||||||
@ -271,7 +259,7 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
|
|||||||
val That = that
|
val That = that
|
||||||
val MinusThat = -that
|
val MinusThat = -that
|
||||||
this match {
|
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, NumericConstant(MinusThat, _), r) => r
|
||||||
case CompoundConstant(Plus, l, NumericConstant(MinusThat, _)) => l
|
case CompoundConstant(Plus, l, NumericConstant(MinusThat, _)) => l
|
||||||
case CompoundConstant(Plus, NumericConstant(x, _), r) => CompoundConstant(Plus, r, NumericConstant(x + that, minimumSize(x + that)))
|
case CompoundConstant(Plus, NumericConstant(x, _), r) => CompoundConstant(Plus, r, NumericConstant(x + that, minimumSize(x + that)))
|
||||||
|
@ -41,7 +41,6 @@ object UnusedFunctions extends NodeOptimization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def getAllCalledFunctions(c: Constant): List[String] = c match {
|
def getAllCalledFunctions(c: Constant): List[String] = c match {
|
||||||
case HalfWordConstant(cc, _) => getAllCalledFunctions(cc)
|
|
||||||
case SubbyteConstant(cc, _) => getAllCalledFunctions(cc)
|
case SubbyteConstant(cc, _) => getAllCalledFunctions(cc)
|
||||||
case CompoundConstant(_, l, r) => getAllCalledFunctions(l) ++ getAllCalledFunctions(r)
|
case CompoundConstant(_, l, r) => getAllCalledFunctions(l) ++ getAllCalledFunctions(r)
|
||||||
case MemoryAddressConstant(th) => List(
|
case MemoryAddressConstant(th) => List(
|
||||||
|
@ -40,7 +40,6 @@ object UnusedGlobalVariables extends NodeOptimization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def getAllReadVariables(c: Constant): List[String] = c match {
|
def getAllReadVariables(c: Constant): List[String] = c match {
|
||||||
case HalfWordConstant(cc, _) => getAllReadVariables(cc)
|
|
||||||
case SubbyteConstant(cc, _) => getAllReadVariables(cc)
|
case SubbyteConstant(cc, _) => getAllReadVariables(cc)
|
||||||
case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r)
|
case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r)
|
||||||
case MemoryAddressConstant(th) => List(th.name.takeWhile(_ != '.'))
|
case MemoryAddressConstant(th) => List(th.name.takeWhile(_ != '.'))
|
||||||
|
@ -29,7 +29,6 @@ object UnusedLocalVariables extends NodeOptimization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def getAllReadVariables(c: Constant): List[String] = c match {
|
def getAllReadVariables(c: Constant): List[String] = c match {
|
||||||
case HalfWordConstant(cc, _) => getAllReadVariables(cc)
|
|
||||||
case SubbyteConstant(cc, _) => getAllReadVariables(cc)
|
case SubbyteConstant(cc, _) => getAllReadVariables(cc)
|
||||||
case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r)
|
case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r)
|
||||||
case MemoryAddressConstant(th) => List(
|
case MemoryAddressConstant(th) => List(
|
||||||
|
@ -97,8 +97,6 @@ class Assembler(private val program: Program, private val rootEnv: Environment,
|
|||||||
case e: StackOverflowError =>
|
case e: StackOverflowError =>
|
||||||
ErrorReporting.fatal("Stack overflow " + c)
|
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 SubbyteConstant(cc, i) => deepConstResolve(cc).>>>(i * 8).&(0xff)
|
||||||
case CompoundConstant(operator, lc, rc) =>
|
case CompoundConstant(operator, lc, rc) =>
|
||||||
val l = deepConstResolve(lc)
|
val l = deepConstResolve(lc)
|
||||||
|
Loading…
Reference in New Issue
Block a user