1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-09-30 00:56:56 +00:00

Do not remove constants used only as array sizes (#51)

This commit is contained in:
Karol Stasiak 2020-07-19 23:34:14 +02:00
parent 27645e93ad
commit 000aede8db
3 changed files with 23 additions and 5 deletions

View File

@ -1676,10 +1676,13 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
case Some(typ) =>
log.error(s"Type $name cannot be used as an array index", l.position)
w -> Constant.Zero
case _ => w -> eval(l).getOrElse(errorConstant(s"Array `${stmt.name}` has non-constant length", stmt.position))
case _ =>
val constant = eval(l).getOrElse(errorConstant(s"Array `${stmt.name}` has non-constant length", stmt.position))
w -> constant
}
case _ =>
w -> eval(l).getOrElse(errorConstant(s"Array `${stmt.name}` has non-constant length", stmt.position))
val constant = eval(l).getOrElse(errorConstant(s"Array `${stmt.name}` has non-constant length", stmt.position))
w -> constant
}
lengthConst match {
case NumericConstant(length, _) =>

View File

@ -16,7 +16,7 @@ object UnusedGlobalVariables extends NodeOptimization {
case _ => None
}.toMap
val allNonvolatileGlobalVariables = nodes.flatMap {
case v: VariableDeclarationStatement => if (v.address.isDefined || v.volatile) Nil else List(v.name)
case v: VariableDeclarationStatement => if (v.address.isDefined || v.volatile || v.constant) Nil else List(v.name)
case v: ArrayDeclarationStatement => if (v.address.isDefined) Nil else List(v.name)
case _ => Nil
}.toSet
@ -50,7 +50,7 @@ object UnusedGlobalVariables extends NodeOptimization {
def getAllReadVariables(expressions: List[Node]): List[String] = expressions.flatMap {
case s: VariableDeclarationStatement => getAllReadVariables(s.address.toList) ++ getAllReadVariables(s.initialValue.toList) ++ (if (s.stack) List("__sp", "__stack") else Nil)
case s: ArrayDeclarationStatement => getAllReadVariables(s.address.toList) ++ getAllReadVariables(s.elements.toList)
case s: ArrayDeclarationStatement => getAllReadVariables(s.address.toList) ++ getAllReadVariables(s.length.toList) ++ getAllReadVariables(s.elements.toList)
case s: ArrayContents => getAllReadVariables(s.getAllExpressions(false)) // endianness doesn't matter here at all
case s: FunctionDeclarationStatement => getAllReadVariables(s.address.toList) ++ getAllReadVariables(s.statements.getOrElse(Nil))
case Assignment(VariableExpression(_), expr) => getAllReadVariables(expr :: Nil)

View File

@ -2,7 +2,7 @@ package millfork.test
import millfork.Cpu
import millfork.env.{BasicPlainType, DerivedPlainType, NumericConstant}
import millfork.test.emu.{EmuUnoptimizedCrossPlatformRun, EmuUnoptimizedRun, ShouldNotCompile}
import millfork.test.emu.{EmuBenchmarkRun, EmuOptimizedCmosRun, EmuUnoptimizedCrossPlatformRun, EmuUnoptimizedRun, ShouldNotCompile}
import org.scalatest.{FunSuite, Matchers}
/**
@ -130,4 +130,19 @@ class ConstantSuite extends FunSuite with Matchers {
m.readByte(0xc011) should equal(89)
}
test("Constant array sizes") {
val m = EmuOptimizedCmosRun(
"""
| const byte A = 8
| const byte B = 8
| const byte SIZE = A * B
| array(byte) arr[SIZE] @$c000
| void main() {
| arr[0] = 1
| }
|
""".stripMargin)
m.readByte(0xc000) should equal(1)
}
}