mirror of
https://github.com/irmen/prog8.git
synced 2024-10-21 04:24:05 +00:00
ir: several fixes
This commit is contained in:
parent
02e51d8282
commit
3126959576
@ -80,6 +80,16 @@ class SymbolTable(astProgram: PtProgram) : StNode(astProgram.name, StNodeType.GL
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun lookup(scopedName: String) = flat[scopedName]
|
override fun lookup(scopedName: String) = flat[scopedName]
|
||||||
|
|
||||||
|
fun getLength(name: String): Int? {
|
||||||
|
val node = flat[name]
|
||||||
|
return when(node) {
|
||||||
|
is StMemVar -> node.length
|
||||||
|
is StMemorySlab -> node.size.toInt()
|
||||||
|
is StStaticVariable -> node.length
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -484,8 +484,8 @@ internal class ProgramAndVarsGen(
|
|||||||
val vars = allocator.zeropageVars.filter { it.value.dt==DataType.STR }
|
val vars = allocator.zeropageVars.filter { it.value.dt==DataType.STR }
|
||||||
for (variable in vars) {
|
for (variable in vars) {
|
||||||
val scopedName = variable.key
|
val scopedName = variable.key
|
||||||
val svar = symboltable.flat.getValue(scopedName) as StStaticVariable
|
val svar = symboltable.lookup(scopedName) as? StStaticVariable
|
||||||
if(svar.onetimeInitializationStringValue!=null)
|
if(svar?.onetimeInitializationStringValue!=null)
|
||||||
result.add(ZpStringWithInitial(scopedName, variable.value, svar.onetimeInitializationStringValue!!))
|
result.add(ZpStringWithInitial(scopedName, variable.value, svar.onetimeInitializationStringValue!!))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -496,8 +496,8 @@ internal class ProgramAndVarsGen(
|
|||||||
val vars = allocator.zeropageVars.filter { it.value.dt in ArrayDatatypes }
|
val vars = allocator.zeropageVars.filter { it.value.dt in ArrayDatatypes }
|
||||||
for (variable in vars) {
|
for (variable in vars) {
|
||||||
val scopedName = variable.key
|
val scopedName = variable.key
|
||||||
val svar = symboltable.flat.getValue(scopedName) as StStaticVariable
|
val svar = symboltable.lookup(scopedName) as? StStaticVariable
|
||||||
if(svar.onetimeInitializationArrayValue!=null)
|
if(svar?.onetimeInitializationArrayValue!=null)
|
||||||
result.add(ZpArrayWithInitial(scopedName, variable.value, svar.onetimeInitializationArrayValue!!))
|
result.add(ZpArrayWithInitial(scopedName, variable.value, svar.onetimeInitializationArrayValue!!))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package prog8.codegen.intermediate
|
package prog8.codegen.intermediate
|
||||||
|
|
||||||
import prog8.code.StStaticVariable
|
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
import prog8.code.core.AssemblyError
|
import prog8.code.core.AssemblyError
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
@ -219,8 +218,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
}
|
}
|
||||||
|
|
||||||
val fixedIndex = constIntValue(targetArray.index)
|
val fixedIndex = constIntValue(targetArray.index)
|
||||||
val iterable = codeGen.symbolTable.flat.getValue(targetArray.variable.name) as StStaticVariable
|
val arrayLength = codeGen.symbolTable.getLength(targetArray.variable.name)
|
||||||
val arrayLength = iterable.length!!
|
|
||||||
if(zero) {
|
if(zero) {
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
val chunk = IRCodeChunk(null, null).also {
|
val chunk = IRCodeChunk(null, null).also {
|
||||||
|
@ -119,7 +119,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
|
|
||||||
private fun funcAny(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcAny(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
val arrayName = call.args[0] as PtIdentifier
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
val array = codeGen.symbolTable.flat.getValue(arrayName.name) as StStaticVariable
|
val array = codeGen.symbolTable.lookup(arrayName.name) as StStaticVariable // TODO FIX/TEST for memory mapped array
|
||||||
val syscall =
|
val syscall =
|
||||||
when (array.dt) {
|
when (array.dt) {
|
||||||
DataType.ARRAY_UB,
|
DataType.ARRAY_UB,
|
||||||
@ -140,7 +140,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
|
|
||||||
private fun funcAll(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcAll(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
val arrayName = call.args[0] as PtIdentifier
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
val array = codeGen.symbolTable.flat.getValue(arrayName.name) as StStaticVariable
|
val array = codeGen.symbolTable.lookup(arrayName.name) as StStaticVariable // TODO FIX/TEST for memory mapped array
|
||||||
val syscall =
|
val syscall =
|
||||||
when(array.dt) {
|
when(array.dt) {
|
||||||
DataType.ARRAY_UB,
|
DataType.ARRAY_UB,
|
||||||
@ -287,7 +287,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
|
|
||||||
private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
val arrayName = call.args[0] as PtIdentifier
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
val array = codeGen.symbolTable.flat.getValue(arrayName.name) as StStaticVariable
|
val array = codeGen.symbolTable.lookup(arrayName.name) as StStaticVariable // TODO FIX/TEST for memory mapped array
|
||||||
val syscall =
|
val syscall =
|
||||||
when(array.dt) {
|
when(array.dt) {
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> IMSyscall.REVERSE_BYTES
|
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> IMSyscall.REVERSE_BYTES
|
||||||
@ -307,7 +307,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
|
|
||||||
private fun funcSort(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcSort(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
val arrayName = call.args[0] as PtIdentifier
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
val array = codeGen.symbolTable.flat.getValue(arrayName.name) as StStaticVariable
|
val array = codeGen.symbolTable.lookup(arrayName.name) as StStaticVariable // TODO FIX/TEST for memory mapped array
|
||||||
val syscall =
|
val syscall =
|
||||||
when(array.dt) {
|
when(array.dt) {
|
||||||
DataType.ARRAY_UB -> IMSyscall.SORT_UBYTE
|
DataType.ARRAY_UB -> IMSyscall.SORT_UBYTE
|
||||||
|
@ -106,7 +106,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
|
|
||||||
private fun translate(check: PtContainmentCheck): ExpressionCodeResult {
|
private fun translate(check: PtContainmentCheck): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val iterable = codeGen.symbolTable.flat.getValue(check.iterable.name) as StStaticVariable
|
val iterable = codeGen.symbolTable.lookup(check.iterable.name) as StStaticVariable // TODO FIX/TEST for memory mapped array , replace with check.iterable.type???
|
||||||
when(iterable.dt) {
|
when(iterable.dt) {
|
||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
val elementTr = translateExpression(check.element)
|
val elementTr = translateExpression(check.element)
|
||||||
@ -164,8 +164,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
|
|
||||||
if(arrayIx.splitWords) {
|
if(arrayIx.splitWords) {
|
||||||
require(vmDt==IRDataType.WORD)
|
require(vmDt==IRDataType.WORD)
|
||||||
val iterable = codeGen.symbolTable.flat.getValue(arrayIx.variable.name) as StStaticVariable
|
val arrayLength = codeGen.symbolTable.getLength(arrayIx.variable.name)
|
||||||
val arrayLength = iterable.length!!
|
|
||||||
resultRegister = codeGen.registers.nextFree()
|
resultRegister = codeGen.registers.nextFree()
|
||||||
if(arrayIx.index is PtNumber) {
|
if(arrayIx.index is PtNumber) {
|
||||||
val memOffset = (arrayIx.index as PtNumber).number.toInt()
|
val memOffset = (arrayIx.index as PtNumber).number.toInt()
|
||||||
|
@ -168,6 +168,11 @@ class IRCodeGen(
|
|||||||
|
|
||||||
replacements.forEach {
|
replacements.forEach {
|
||||||
val old = it.first.instructions[it.second]
|
val old = it.first.instructions[it.second]
|
||||||
|
val formats = instructionFormats.getValue(old.opcode)
|
||||||
|
val format = formats.getOrElse(old.type) { throw IllegalArgumentException("type ${old.type} invalid for ${old.opcode}") }
|
||||||
|
val immediateValue = if(format.immediate) it.third.toInt() else null
|
||||||
|
val addressValue = if(format.immediate) null else it.third.toInt()
|
||||||
|
|
||||||
it.first.instructions[it.second] = IRInstruction(
|
it.first.instructions[it.second] = IRInstruction(
|
||||||
old.opcode,
|
old.opcode,
|
||||||
old.type,
|
old.type,
|
||||||
@ -175,9 +180,9 @@ class IRCodeGen(
|
|||||||
old.reg2,
|
old.reg2,
|
||||||
old.fpReg1,
|
old.fpReg1,
|
||||||
old.fpReg2,
|
old.fpReg2,
|
||||||
|
immediate = immediateValue,
|
||||||
null,
|
null,
|
||||||
null,
|
address = addressValue,
|
||||||
address = it.third.toInt(),
|
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
@ -447,60 +452,63 @@ class IRCodeGen(
|
|||||||
result += translateForInNonConstantRange(forLoop, loopvar)
|
result += translateForInNonConstantRange(forLoop, loopvar)
|
||||||
}
|
}
|
||||||
is PtIdentifier -> {
|
is PtIdentifier -> {
|
||||||
val iterableVar = symbolTable.lookup(iterable.name) as StStaticVariable
|
|
||||||
require(forLoop.variable.name == loopvar.scopedName)
|
require(forLoop.variable.name == loopvar.scopedName)
|
||||||
|
val iterableLength = symbolTable.getLength(iterable.name)
|
||||||
val loopvarSymbol = forLoop.variable.name
|
val loopvarSymbol = forLoop.variable.name
|
||||||
val indexReg = registers.nextFree()
|
val indexReg = registers.nextFree()
|
||||||
val tmpReg = registers.nextFree()
|
val tmpReg = registers.nextFree()
|
||||||
val loopLabel = createLabelName()
|
val loopLabel = createLabelName()
|
||||||
val endLabel = createLabelName()
|
val endLabel = createLabelName()
|
||||||
if(iterableVar.dt==DataType.STR) {
|
when (iterable.type) {
|
||||||
// iterate over a zero-terminated string
|
DataType.STR -> {
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = 0), null)
|
// iterate over a zero-terminated string
|
||||||
result += IRCodeChunk(loopLabel, null).also {
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = 0), null)
|
||||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1 = tmpReg, reg2 = indexReg, labelSymbol = iterable.name)
|
result += IRCodeChunk(loopLabel, null).also {
|
||||||
it += IRInstruction(Opcode.BEQ, IRDataType.BYTE, reg1 = tmpReg, immediate = 0, labelSymbol = endLabel)
|
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1 = tmpReg, reg2 = indexReg, labelSymbol = iterable.name)
|
||||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tmpReg, labelSymbol = loopvarSymbol)
|
it += IRInstruction(Opcode.BEQ, IRDataType.BYTE, reg1 = tmpReg, immediate = 0, labelSymbol = endLabel)
|
||||||
|
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tmpReg, labelSymbol = loopvarSymbol)
|
||||||
|
}
|
||||||
|
result += translateNode(forLoop.statements)
|
||||||
|
val jumpChunk = IRCodeChunk(null, null)
|
||||||
|
jumpChunk += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1 = indexReg)
|
||||||
|
jumpChunk += IRInstruction(Opcode.JUMP, labelSymbol = loopLabel)
|
||||||
|
result += jumpChunk
|
||||||
|
result += IRCodeChunk(endLabel, null)
|
||||||
}
|
}
|
||||||
result += translateNode(forLoop.statements)
|
in SplitWordArrayTypes -> {
|
||||||
val jumpChunk = IRCodeChunk(null, null)
|
// iterate over lsb/msb split word array
|
||||||
jumpChunk += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1 = indexReg)
|
val elementDt = ArrayToElementTypes.getValue(iterable.type)
|
||||||
jumpChunk += IRInstruction(Opcode.JUMP, labelSymbol = loopLabel)
|
if(elementDt !in WordDatatypes)
|
||||||
result += jumpChunk
|
throw AssemblyError("weird dt")
|
||||||
result += IRCodeChunk(endLabel, null)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, immediate = 0), null)
|
||||||
} else if(iterable.type in SplitWordArrayTypes) {
|
result += IRCodeChunk(loopLabel, null).also {
|
||||||
// iterate over lsb/msb split word array
|
val tmpRegLsb = registers.nextFree()
|
||||||
val elementDt = ArrayToElementTypes.getValue(iterable.type)
|
val tmpRegMsb = registers.nextFree()
|
||||||
if(elementDt !in WordDatatypes)
|
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpRegLsb, reg2=indexReg, immediate = iterableLength, labelSymbol=iterable.name+"_lsb")
|
||||||
throw AssemblyError("weird dt")
|
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpRegMsb, reg2=indexReg, immediate = iterableLength, labelSymbol=iterable.name+"_msb")
|
||||||
val length = iterableVar.length!!
|
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1=tmpRegLsb, reg2=tmpRegMsb)
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, immediate = 0), null)
|
it += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpRegLsb, labelSymbol = loopvarSymbol)
|
||||||
result += IRCodeChunk(loopLabel, null).also {
|
}
|
||||||
val tmpRegLsb = registers.nextFree()
|
result += translateNode(forLoop.statements)
|
||||||
val tmpRegMsb = registers.nextFree()
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpRegLsb, reg2=indexReg, immediate = length, labelSymbol=iterable.name+"_lsb")
|
it += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=indexReg)
|
||||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpRegMsb, reg2=indexReg, immediate = length, labelSymbol=iterable.name+"_msb")
|
it += IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=indexReg, immediate = if(iterableLength==256) 0 else iterableLength, labelSymbol = loopLabel)
|
||||||
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1=tmpRegLsb, reg2=tmpRegMsb)
|
}
|
||||||
it += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpRegLsb, labelSymbol = loopvarSymbol)
|
|
||||||
}
|
}
|
||||||
result += translateNode(forLoop.statements)
|
else -> {
|
||||||
result += IRCodeChunk(null, null).also {
|
// iterate over regular array
|
||||||
it += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=indexReg)
|
val elementDt = ArrayToElementTypes.getValue(iterable.type)
|
||||||
it += IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=indexReg, immediate = if(length==256) 0 else length, labelSymbol = loopLabel)
|
val elementSize = program.memsizer.memorySize(elementDt)
|
||||||
|
val lengthBytes = iterableLength!! * elementSize
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, immediate = 0), null)
|
||||||
|
result += IRCodeChunk(loopLabel, null).also {
|
||||||
|
it += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=iterable.name)
|
||||||
|
it += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
|
||||||
|
}
|
||||||
|
result += translateNode(forLoop.statements)
|
||||||
|
result += addConstReg(IRDataType.BYTE, indexReg, elementSize)
|
||||||
|
addInstr(result, IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=indexReg, immediate = if(lengthBytes==256) 0 else lengthBytes, labelSymbol = loopLabel), null)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// iterate over regular array
|
|
||||||
val elementDt = ArrayToElementTypes.getValue(iterable.type)
|
|
||||||
val elementSize = program.memsizer.memorySize(elementDt)
|
|
||||||
val lengthBytes = iterableVar.length!! * elementSize
|
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, immediate = 0), null)
|
|
||||||
result += IRCodeChunk(loopLabel, null).also {
|
|
||||||
it += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=iterable.name)
|
|
||||||
it += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
|
|
||||||
}
|
|
||||||
result += translateNode(forLoop.statements)
|
|
||||||
result += addConstReg(IRDataType.BYTE, indexReg, elementSize)
|
|
||||||
addInstr(result, IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=indexReg, immediate = if(lengthBytes==256) 0 else lengthBytes, labelSymbol = loopLabel), null)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird for iterable")
|
else -> throw AssemblyError("weird for iterable")
|
||||||
@ -1362,7 +1370,6 @@ class IRCodeGen(
|
|||||||
if(array?.splitWords==true) {
|
if(array?.splitWords==true) {
|
||||||
val variable = array.variable.name
|
val variable = array.variable.name
|
||||||
val fixedIndex = constIntValue(array.index)
|
val fixedIndex = constIntValue(array.index)
|
||||||
val iterable = symbolTable.flat.getValue(array.variable.name) as StStaticVariable
|
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
val skipLabel = createLabelName()
|
val skipLabel = createLabelName()
|
||||||
when(postIncrDecr.operator) {
|
when(postIncrDecr.operator) {
|
||||||
@ -1388,7 +1395,7 @@ class IRCodeGen(
|
|||||||
else -> throw AssemblyError("weird operator")
|
else -> throw AssemblyError("weird operator")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val arrayLength = iterable.length!!
|
val arrayLength = symbolTable.getLength(array.variable.name)
|
||||||
val indexTr = expressionEval.translateExpression(array.index)
|
val indexTr = expressionEval.translateExpression(array.index)
|
||||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||||
val incReg = registers.nextFree()
|
val incReg = registers.nextFree()
|
||||||
@ -1611,7 +1618,7 @@ class IRCodeGen(
|
|||||||
private fun translate(parameters: List<PtSubroutineParameter>) =
|
private fun translate(parameters: List<PtSubroutineParameter>) =
|
||||||
parameters.map {
|
parameters.map {
|
||||||
val flattenedName = it.definingSub()!!.name + "." + it.name
|
val flattenedName = it.definingSub()!!.name + "." + it.name
|
||||||
val orig = symbolTable.flat.getValue(flattenedName) as StStaticVariable
|
val orig = symbolTable.lookup(flattenedName) as StStaticVariable // TODO FIX/TEST for memory mapped array or other
|
||||||
IRSubroutine.IRParam(flattenedName, orig.dt)
|
IRSubroutine.IRParam(flattenedName, orig.dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +139,18 @@ class IRUnusedCodeRemover(
|
|||||||
.children.single { it is IRSubroutine && it.label=="main.start" }
|
.children.single { it is IRSubroutine && it.label=="main.start" }
|
||||||
val reachable = mutableSetOf((entrypointSub as IRSubroutine).chunks.first())
|
val reachable = mutableSetOf((entrypointSub as IRSubroutine).chunks.first())
|
||||||
|
|
||||||
|
// all chunks referenced in array initializer values are also 'reachable':
|
||||||
|
irprog.st.allVariables()
|
||||||
|
.filter { !it.uninitialized }
|
||||||
|
.forEach {
|
||||||
|
it.onetimeInitializationArrayValue?.let { array ->
|
||||||
|
array.forEach {elt ->
|
||||||
|
if(elt.addressOfSymbol!=null && irprog.st.lookup(elt.addressOfSymbol!!)==null)
|
||||||
|
reachable.add(irprog.getChunkWithLabel(elt.addressOfSymbol!!))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun grow() {
|
fun grow() {
|
||||||
val new = mutableSetOf<IRCodeChunkBase>()
|
val new = mutableSetOf<IRCodeChunkBase>()
|
||||||
reachable.forEach {
|
reachable.forEach {
|
||||||
@ -167,6 +179,18 @@ class IRUnusedCodeRemover(
|
|||||||
private fun removeSimpleUnlinked(allLabeledChunks: Map<String, IRCodeChunkBase>): Int {
|
private fun removeSimpleUnlinked(allLabeledChunks: Map<String, IRCodeChunkBase>): Int {
|
||||||
val linkedChunks = mutableSetOf<IRCodeChunkBase>()
|
val linkedChunks = mutableSetOf<IRCodeChunkBase>()
|
||||||
|
|
||||||
|
// all chunks referenced in array initializer values are linked as well!:
|
||||||
|
irprog.st.allVariables()
|
||||||
|
.filter { !it.uninitialized }
|
||||||
|
.forEach {
|
||||||
|
it.onetimeInitializationArrayValue?.let { array ->
|
||||||
|
array.forEach {elt ->
|
||||||
|
if(elt.addressOfSymbol!=null && irprog.st.lookup(elt.addressOfSymbol!!)==null)
|
||||||
|
linkedChunks += irprog.getChunkWithLabel(elt.addressOfSymbol!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
irprog.foreachCodeChunk { chunk ->
|
irprog.foreachCodeChunk { chunk ->
|
||||||
chunk.next?.let { next -> linkedChunks += next }
|
chunk.next?.let { next -> linkedChunks += next }
|
||||||
chunk.instructions.forEach {
|
chunk.instructions.forEach {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- Fix wrong unused subroutines in expericodegen with cx16 shell
|
- Fix possible ST type error: // TODO FIX/TEST for memory mapped array
|
||||||
- Fix expericodegen errors (chess, assem, musicdemo, rockrunners etc)
|
- Fix expericodegen errors (chess, assem, musicdemo, rockrunners)
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@ -1,10 +1,21 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
romsub $FFD2 = chrout(ubyte ch @ A)
|
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte ch = '2'
|
; uword[] routines = [ 0, &command, $4444 ]
|
||||||
chrout(ch)
|
; cx16.r0 = routines[1]
|
||||||
|
|
||||||
|
&ubyte[5] cells = $4000
|
||||||
|
cells = [1,2,3,4,5]
|
||||||
|
ubyte ub
|
||||||
|
for ub in cells {
|
||||||
|
txt.print_ub(ub)
|
||||||
|
txt.spc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub command() {
|
||||||
|
cx16.r0++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,15 @@ class IRProgram(val name: String,
|
|||||||
fun allSubs(): Sequence<IRSubroutine> = blocks.asSequence().flatMap { it.children.filterIsInstance<IRSubroutine>() }
|
fun allSubs(): Sequence<IRSubroutine> = blocks.asSequence().flatMap { it.children.filterIsInstance<IRSubroutine>() }
|
||||||
fun foreachSub(operation: (sub: IRSubroutine) -> Unit) = allSubs().forEach { operation(it) }
|
fun foreachSub(operation: (sub: IRSubroutine) -> Unit) = allSubs().forEach { operation(it) }
|
||||||
fun foreachCodeChunk(operation: (chunk: IRCodeChunkBase) -> Unit) = allSubs().flatMap { it.chunks }.forEach { operation(it) }
|
fun foreachCodeChunk(operation: (chunk: IRCodeChunkBase) -> Unit) = allSubs().flatMap { it.chunks }.forEach { operation(it) }
|
||||||
|
fun getChunkWithLabel(label: String): IRCodeChunkBase {
|
||||||
|
for(sub in allSubs()) {
|
||||||
|
for(chunk in sub.chunks) {
|
||||||
|
if(chunk.label==label)
|
||||||
|
return chunk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw NoSuchElementException("no chunk with label '$label'")
|
||||||
|
}
|
||||||
|
|
||||||
fun addGlobalInits(chunk: IRCodeChunk) {
|
fun addGlobalInits(chunk: IRCodeChunk) {
|
||||||
globalInits += chunk
|
globalInits += chunk
|
||||||
|
Loading…
Reference in New Issue
Block a user