mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +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
|
// 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")) {
|
if(functionCallStatement.target.nameInSource==listOf("txt", "print")) {
|
||||||
val arg = functionCallStatement.args.single()
|
val arg = functionCallStatement.args.single()
|
||||||
val stringVar: IdentifierReference? = if(arg is AddressOf) {
|
val stringVar: IdentifierReference? = if(arg is AddressOf) {
|
||||||
@ -55,10 +56,7 @@ internal class StatementOptimizer(private val program: Program,
|
|||||||
} else {
|
} else {
|
||||||
arg as? IdentifierReference
|
arg as? IdentifierReference
|
||||||
}
|
}
|
||||||
if(stringVar!=null) {
|
if(stringVar!=null && stringVar.wasStringLiteral(program)) {
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
val string = stringVar.targetVarDecl(program)?.value as? StringLiteralValue
|
val string = stringVar.targetVarDecl(program)?.value as? StringLiteralValue
|
||||||
if(string!=null) {
|
if(string!=null) {
|
||||||
val pos = functionCallStatement.position
|
val pos = functionCallStatement.position
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package prog8.optimizer
|
package prog8.optimizer
|
||||||
|
|
||||||
import prog8.ast.INameScope
|
import prog8.ast.*
|
||||||
import prog8.ast.Module
|
|
||||||
import prog8.ast.Node
|
|
||||||
import prog8.ast.Program
|
|
||||||
import prog8.ast.base.VarDeclType
|
import prog8.ast.base.VarDeclType
|
||||||
import prog8.ast.expressions.BinaryExpression
|
import prog8.ast.expressions.BinaryExpression
|
||||||
import prog8.ast.expressions.FunctionCall
|
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> {
|
override fun after(block: Block, parent: Node): Iterable<IAstModification> {
|
||||||
if("force_output" !in block.options()) {
|
if("force_output" !in block.options()) {
|
||||||
if (block.containsNoCodeNorVars()) {
|
if (block.containsNoCodeNorVars()) {
|
||||||
if(block.name != program.internedStringsModuleName)
|
if(block.name != internedStringsModuleName)
|
||||||
errors.warn("removing unused block '${block.name}'", block.position)
|
errors.warn("removing unused block '${block.name}'", block.position)
|
||||||
return listOf(IAstModification.Remove(block, parent as INameScope))
|
return listOf(IAstModification.Remove(block, parent as INameScope))
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ import prog8.ast.walk.IAstVisitor
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
const val internedStringsModuleName = "prog8_interned_strings"
|
||||||
|
|
||||||
interface IStringEncoding {
|
interface IStringEncoding {
|
||||||
fun encodeString(str: String, altEncoding: Boolean): List<Short>
|
fun encodeString(str: String, altEncoding: Boolean): List<Short>
|
||||||
fun decodeString(bytes: List<Short>, altEncoding: Boolean): String
|
fun decodeString(bytes: List<Short>, altEncoding: Boolean): String
|
||||||
@ -257,7 +259,6 @@ class Program(val name: String,
|
|||||||
|
|
||||||
var actualLoadAddress: Int = 0
|
var actualLoadAddress: Int = 0
|
||||||
private val internedStringsUnique = mutableMapOf<Pair<String, Boolean>, List<String>>()
|
private val internedStringsUnique = mutableMapOf<Pair<String, Boolean>, List<String>>()
|
||||||
val internedStringsModuleName = "prog8_interned_strings"
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// insert a container module for all interned strings later
|
// 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()
|
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,
|
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?
|
- 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???
|
However: who even needs variables declared in prog8 code that are only used by assembly???
|
||||||
|
|
||||||
- github issue about strings and their immutability:
|
- 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.
|
IMPROVE DOCUMENTATION ABOUT STRINGS AND DEDUP and (NON)IMMUTABILITY.
|
||||||
|
|
||||||
- test all examples (including imgviewer, assembler and petaxian) before release of the new version
|
- test all examples (including imgviewer, assembler and petaxian) before release of the new version
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
%import textio ; txt.*
|
%import textio ; txt.*
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
main {
|
main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
str string1 = "stringvalue"
|
str string1 = "stringvalue\n"
|
||||||
str string2 = "stringvalue"
|
str string2 = "stringvalue\n"
|
||||||
str string3 = "stringvalue"
|
str string3 = "stringvalue\n"
|
||||||
|
str string4 = "a"
|
||||||
|
str string5 = "bb"
|
||||||
|
|
||||||
txt.print("a")
|
txt.print("a")
|
||||||
txt.print("a")
|
txt.print("a")
|
||||||
|
txt.print(string4)
|
||||||
txt.print("bb")
|
txt.print("bb")
|
||||||
txt.print("bb")
|
txt.print("bb")
|
||||||
|
txt.print(string5)
|
||||||
txt.print("\n")
|
txt.print("\n")
|
||||||
txt.print("\n\n")
|
txt.print("\n\n")
|
||||||
txt.print(string1)
|
txt.print(string1)
|
||||||
txt.nl()
|
|
||||||
txt.print(string2)
|
txt.print(string2)
|
||||||
txt.nl()
|
|
||||||
txt.print(string3)
|
txt.print(string3)
|
||||||
txt.nl()
|
|
||||||
txt.print("hello\n")
|
txt.print("hello\n")
|
||||||
txt.print("hello\n")
|
txt.print("hello\n")
|
||||||
txt.print("hello\n")
|
txt.print("hello\n")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user