diff --git a/src/main/scala/millfork/assembly/AbstractCode.scala b/src/main/scala/millfork/assembly/AbstractCode.scala index ab9c997a..0bd65dc8 100644 --- a/src/main/scala/millfork/assembly/AbstractCode.scala +++ b/src/main/scala/millfork/assembly/AbstractCode.scala @@ -7,6 +7,8 @@ import millfork.node.Position * @author Karol Stasiak */ trait AbstractCode { + def refersTo(name: String): Boolean + def sizeInBytes: Int def isPrintable: Boolean diff --git a/src/main/scala/millfork/assembly/mos/AssemblyLine.scala b/src/main/scala/millfork/assembly/mos/AssemblyLine.scala index 4c157643..c678b0af 100644 --- a/src/main/scala/millfork/assembly/mos/AssemblyLine.scala +++ b/src/main/scala/millfork/assembly/mos/AssemblyLine.scala @@ -527,6 +527,8 @@ case class AssemblyLine(opcode: Opcode.Value, addrMode: AddrMode.Value, var para @inline def notFixed: Boolean = elidability != Elidability.Fixed + def refersTo(name: String): Boolean = parameter.refersTo(name) + import AddrMode._ import OpcodeClasses._ import State._ diff --git a/src/main/scala/millfork/assembly/z80/ZLine.scala b/src/main/scala/millfork/assembly/z80/ZLine.scala index 1fd31cba..a854231a 100644 --- a/src/main/scala/millfork/assembly/z80/ZLine.scala +++ b/src/main/scala/millfork/assembly/z80/ZLine.scala @@ -234,6 +234,8 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta @inline def notFixed: Boolean = elidability != Elidability.Fixed + def refersTo(name: String): Boolean = parameter.refersTo(name) + override def sizeInBytes: Int = { import ZOpcode._ import ZRegister._ diff --git a/src/main/scala/millfork/env/Constant.scala b/src/main/scala/millfork/env/Constant.scala index a79d4f7f..a64643bd 100644 --- a/src/main/scala/millfork/env/Constant.scala +++ b/src/main/scala/millfork/env/Constant.scala @@ -95,6 +95,8 @@ sealed trait Constant { def isRelatedTo(v: Thing): Boolean + def refersTo(name: String): Boolean + def fitsInto(typ: Type): Boolean = true // TODO } @@ -109,6 +111,8 @@ case class AssertByte(c: Constant) extends Constant { override def isRelatedTo(v: Thing): Boolean = c.isRelatedTo(v) + override def refersTo(name: String): Boolean = c.refersTo(name) + override def quickSimplify: Constant = AssertByte(c.quickSimplify) override def fitsInto(typ: Type): Boolean = true @@ -121,6 +125,8 @@ case class UnexpandedConstant(name: String, requiredSize: Int) extends Constant override def toString: String = name override def toIntelString: String = name + + override def refersTo(name: String): Boolean = name == this.name } case class NumericConstant(value: Long, requiredSize: Int) extends Constant { @@ -162,6 +168,8 @@ case class NumericConstant(value: Long, requiredSize: Int) extends Constant { override def isRelatedTo(v: Thing): Boolean = false + override def refersTo(name: String): Boolean = false + override def fitsInto(typ: Type): Boolean = { if (typ.isSigned) { typ.size match { @@ -207,6 +215,8 @@ case class MemoryAddressConstant(var thing: ThingInMemory) extends Constant { override def toIntelString: String = thing.name override def isRelatedTo(v: Thing): Boolean = thing.name == v.name + + override def refersTo(name: String): Boolean = name == thing.name } case class SubbyteConstant(base: Constant, index: Int) extends Constant { @@ -241,6 +251,8 @@ case class SubbyteConstant(base: Constant, index: Int) extends Constant { } override def isRelatedTo(v: Thing): Boolean = base.isRelatedTo(v) + + override def refersTo(name: String): Boolean = base.refersTo(name) } object MathOperator extends Enumeration { @@ -483,4 +495,6 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co } override def isRelatedTo(v: Thing): Boolean = lhs.isRelatedTo(v) || rhs.isRelatedTo(v) -} \ No newline at end of file + + override def refersTo(name: String): Boolean = lhs.refersTo(name) || rhs.refersTo(name) +} diff --git a/src/main/scala/millfork/output/AbstractAssembler.scala b/src/main/scala/millfork/output/AbstractAssembler.scala index 2952ee9b..4c3616a5 100644 --- a/src/main/scala/millfork/output/AbstractAssembler.scala +++ b/src/main/scala/millfork/output/AbstractAssembler.scala @@ -240,7 +240,16 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program } } - env.allPreallocatables.foreach { + val unusedRuntimeObjects = Set("__mul_u8u8u8", "__constant8", "identity$", "__mul_u16u8u16").filterNot(name =>{ + compiledFunctions.exists{ + case (fname, compiled) => fname != name && (compiled match { + case f:NormalCompiledFunction[_] => f.code.exists(_.refersTo(name)) + case _ => false + }) + } + }) + + env.allPreallocatables.filterNot(o => unusedRuntimeObjects(o.name)).foreach { case thing@InitializedArray(name, Some(NumericConstant(address, _)), items, _, _, _, _) => val bank = thing.bank(options) val bank0 = mem.banks(bank) @@ -289,7 +298,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program var justAfterCode = platform.codeAllocators.mapValues(a => a.startAt) val sortedCompilerFunctions = compiledFunctions.toList.sortBy { case (name, cf) => if (name == "main") 0 -> "" else cf.orderKey } - sortedCompilerFunctions.foreach { + sortedCompilerFunctions.filterNot(o => unusedRuntimeObjects(o._1)).foreach { case (_, NormalCompiledFunction(_, _, true, _)) => // already done before case (name, NormalCompiledFunction(bank, code, false, alignment)) => @@ -344,7 +353,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program assembly.append(" " + bytePseudoopcode + " 2 ;; end of LUnix relocatable segment") justAfterCode += "default" -> (index + 1) } - env.allPreallocatables.foreach { + env.allPreallocatables.filterNot(o => unusedRuntimeObjects(o.name)).foreach { case thing@InitializedArray(name, None, items, _, _, _, alignment) => val bank = thing.bank(options) val bank0 = mem.banks(bank)