mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
printing 2-letter strings is now only optimized into direct CHROUT if it's a const string literal
This commit is contained in:
parent
68d7b4649e
commit
ca61248861
@ -48,6 +48,7 @@ internal class StatementOptimizer(private val program: Program,
|
||||
}
|
||||
|
||||
// printing a literal string of just 2 or 1 characters is replaced by directly outputting those characters
|
||||
// only do this optimization if the arg is a known-constant string literal instead of a user defined variable.
|
||||
if(functionCallStatement.target.nameInSource==listOf("txt", "print")) {
|
||||
val arg = functionCallStatement.args.single()
|
||||
val stringVar: IdentifierReference? = if(arg is AddressOf) {
|
||||
@ -55,10 +56,7 @@ internal class StatementOptimizer(private val program: Program,
|
||||
} else {
|
||||
arg as? IdentifierReference
|
||||
}
|
||||
if(stringVar!=null) {
|
||||
|
||||
// TODO: only do this optimization if the arg is a known-constant string literal instead of a user defined variable. We can't see the difference here yet.
|
||||
|
||||
if(stringVar!=null && stringVar.wasStringLiteral(program)) {
|
||||
val string = stringVar.targetVarDecl(program)?.value as? StringLiteralValue
|
||||
if(string!=null) {
|
||||
val pos = functionCallStatement.position
|
||||
|
@ -1,9 +1,6 @@
|
||||
package prog8.optimizer
|
||||
|
||||
import prog8.ast.INameScope
|
||||
import prog8.ast.Module
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.*
|
||||
import prog8.ast.base.VarDeclType
|
||||
import prog8.ast.expressions.BinaryExpression
|
||||
import prog8.ast.expressions.FunctionCall
|
||||
@ -65,7 +62,7 @@ internal class UnusedCodeRemover(private val program: Program,
|
||||
override fun after(block: Block, parent: Node): Iterable<IAstModification> {
|
||||
if("force_output" !in block.options()) {
|
||||
if (block.containsNoCodeNorVars()) {
|
||||
if(block.name != program.internedStringsModuleName)
|
||||
if(block.name != internedStringsModuleName)
|
||||
errors.warn("removing unused block '${block.name}'", block.position)
|
||||
return listOf(IAstModification.Remove(block, parent as INameScope))
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import prog8.ast.walk.IAstVisitor
|
||||
import java.nio.file.Path
|
||||
import kotlin.math.abs
|
||||
|
||||
const val internedStringsModuleName = "prog8_interned_strings"
|
||||
|
||||
interface IStringEncoding {
|
||||
fun encodeString(str: String, altEncoding: Boolean): List<Short>
|
||||
fun decodeString(bytes: List<Short>, altEncoding: Boolean): String
|
||||
@ -257,7 +259,6 @@ class Program(val name: String,
|
||||
|
||||
var actualLoadAddress: Int = 0
|
||||
private val internedStringsUnique = mutableMapOf<Pair<String, Boolean>, List<String>>()
|
||||
val internedStringsModuleName = "prog8_interned_strings"
|
||||
|
||||
init {
|
||||
// insert a container module for all interned strings later
|
||||
|
@ -788,6 +788,15 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
||||
else -> InferredTypes.InferredType.unknown()
|
||||
}
|
||||
}
|
||||
|
||||
fun wasStringLiteral(program: Program): Boolean {
|
||||
val decl = targetVarDecl(program)
|
||||
if(decl == null || !decl.autogeneratedDontRemove)
|
||||
return false
|
||||
|
||||
val scope=decl.definingModule()
|
||||
return scope.name==internedStringsModuleName
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionCall(override var target: IdentifierReference,
|
||||
|
@ -4,8 +4,9 @@ TODO
|
||||
|
||||
- possible idea: option to mark vardecls 'shared' to indicate they should not be optimized away because they're shared with assembly code?
|
||||
However: who even needs variables declared in prog8 code that are only used by assembly???
|
||||
|
||||
- github issue about strings and their immutability:
|
||||
StatementOptimizer line 60: only optimize when it's a known constant literal
|
||||
Can we make deduplication the default again? (only string literals are considered...) remove cli option for it again?
|
||||
IMPROVE DOCUMENTATION ABOUT STRINGS AND DEDUP and (NON)IMMUTABILITY.
|
||||
|
||||
- test all examples (including imgviewer, assembler and petaxian) before release of the new version
|
||||
|
@ -1,24 +1,26 @@
|
||||
%import textio ; txt.*
|
||||
%zeropage basicsafe
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
||||
str string1 = "stringvalue"
|
||||
str string2 = "stringvalue"
|
||||
str string3 = "stringvalue"
|
||||
str string1 = "stringvalue\n"
|
||||
str string2 = "stringvalue\n"
|
||||
str string3 = "stringvalue\n"
|
||||
str string4 = "a"
|
||||
str string5 = "bb"
|
||||
|
||||
txt.print("a")
|
||||
txt.print("a")
|
||||
txt.print(string4)
|
||||
txt.print("bb")
|
||||
txt.print("bb")
|
||||
txt.print(string5)
|
||||
txt.print("\n")
|
||||
txt.print("\n\n")
|
||||
txt.print(string1)
|
||||
txt.nl()
|
||||
txt.print(string2)
|
||||
txt.nl()
|
||||
txt.print(string3)
|
||||
txt.nl()
|
||||
txt.print("hello\n")
|
||||
txt.print("hello\n")
|
||||
txt.print("hello\n")
|
||||
|
Loading…
x
Reference in New Issue
Block a user