From a521982576b3ac4ef81d33108c7611ea5002555e Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 9 Jun 2023 21:45:05 +0200 Subject: [PATCH] fix subroutine inline problem with strings --- .../intermediate/IRUnusedCodeRemover.kt | 18 +++++++++++++- .../src/prog8/optimizer/UnusedCodeRemover.kt | 4 +++- .../test/codegeneration/TestVariousCodeGen.kt | 24 +++++++++++++++++++ docs/source/todo.rst | 4 ---- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt index ce063a328..7149dee03 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt @@ -16,7 +16,7 @@ class IRUnusedCodeRemover( irprog.blocks.reversed().forEach { block -> if(block.isEmpty()) { irprog.blocks.remove(block) - irprog.st.removeTree(block.label) + pruneSymboltable(block.label) numRemoved++ } } @@ -24,6 +24,22 @@ class IRUnusedCodeRemover( return numRemoved } + private fun pruneSymboltable(blockLabel: String) { + // we could clean up the SymbolTable as well, but ONLY if these symbols aren't referenced somewhere still in an instruction + val prefix = "$blockLabel." + val blockVars = irprog.st.allVariables().filter { it.name.startsWith(prefix) } + blockVars.forEach { stVar -> + irprog. allSubs().flatMap { it.chunks }.forEach { chunk -> + chunk.instructions.forEach { ins -> + if(ins.labelSymbol == stVar.name) { + return + } + } + } + } + irprog.st.removeTree(blockLabel) + } + private fun removeUnusedSubroutines(): Int { val allLabeledChunks = mutableMapOf() irprog.foreachCodeChunk { chunk -> diff --git a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt index 10c301681..a83eac02a 100644 --- a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt +++ b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt @@ -75,7 +75,9 @@ class UnusedCodeRemover(private val program: Program, if(!block.statements.any { it is Subroutine && it.hasBeenInlined }) errors.warn("removing unused block '${block.name}'", block.position) } - program.removeInternedStringsFromRemovedBlock(block) + if(!block.statements.any { it is Subroutine && it.hasBeenInlined }) { + program.removeInternedStringsFromRemovedBlock(block) + } return listOf(IAstModification.Remove(block, parent as IStatementContainer)) } } diff --git a/compiler/test/codegeneration/TestVariousCodeGen.kt b/compiler/test/codegeneration/TestVariousCodeGen.kt index 429d925ef..3ecf3a101 100644 --- a/compiler/test/codegeneration/TestVariousCodeGen.kt +++ b/compiler/test/codegeneration/TestVariousCodeGen.kt @@ -178,4 +178,28 @@ main { }""" compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null } + + test("string vars in inlined subroutines are ok") { + val src=""" +main { + sub start() { + void block2.curdir() + void block2.other() + } +} + +block2 { + str result="zzzz" + sub curdir() -> str { + return result + } + + sub other() -> str { + return "other" + } +}""" + + compileText(C64Target(), true, src, writeAssembly = true) shouldNotBe null + compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null + } }) \ No newline at end of file diff --git a/docs/source/todo.rst b/docs/source/todo.rst index c2eeab403..652550ecf 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,10 +1,6 @@ TODO ==== -- fix undefined symbol error for sub curdir() -> str { return "todo" } -- fix placeholder error for - str result = "todo" , sub curdir() -> str { return result } - - document some library modules better (diskio, etc) ...