slightly optimized certain list iterations into sequences

This commit is contained in:
Irmen de Jong 2022-01-10 23:15:24 +01:00
parent 789e39c719
commit de3b2fb95b
8 changed files with 24 additions and 23 deletions

View File

@ -218,7 +218,7 @@ class AsmGen(private val program: Program,
out("${block.name}\t" + (if("force_output" in block.options()) ".block\n" else ".proc\n"))
if(options.dontReinitGlobals) {
block.statements.filterIsInstance<VarDecl>().forEach {
block.statements.asSequence().filterIsInstance<VarDecl>().forEach {
it.zeropage = ZeropageWish.NOT_IN_ZEROPAGE
val init = it.nextSibling() as? Assignment
if(init?.target?.identifier?.targetVarDecl(program) === it) {
@ -236,7 +236,7 @@ class AsmGen(private val program: Program,
memdefs2asm(block.statements, block)
vardecls2asm(block.statements, block)
block.statements.filterIsInstance<VarDecl>().forEach {
block.statements.asSequence().filterIsInstance<VarDecl>().forEach {
if(it.type==VarDeclType.VAR && it.datatype in NumericDatatypes)
it.value=null
}
@ -285,7 +285,7 @@ class AsmGen(private val program: Program,
private fun zeropagevars2asm(statements: List<Statement>, inBlock: Block?) {
out("; vars allocated on zeropage")
val variables = statements.filterIsInstance<VarDecl>().filter { it.type==VarDeclType.VAR }
val variables = statements.asSequence().filterIsInstance<VarDecl>().filter { it.type==VarDeclType.VAR }
val blockname = inBlock?.name
for(variable in variables) {
if(blockname=="prog8_lib" && variable.name.startsWith("P8ZP_SCRATCH_"))
@ -414,7 +414,7 @@ class AsmGen(private val program: Program,
val blockname = inBlock?.name
out("\n; memdefs and kernal subroutines")
val memvars = statements.filterIsInstance<VarDecl>().filter { it.type==VarDeclType.MEMORY || it.type==VarDeclType.CONST }
val memvars = statements.asSequence().filterIsInstance<VarDecl>().filter { it.type==VarDeclType.MEMORY || it.type==VarDeclType.CONST }
for(m in memvars) {
if(blockname!="prog8_lib" || !m.name.startsWith("P8ZP_SCRATCH_")) // the "hooks" to the temp vars are not generated as new variables
if(m.value is NumericLiteralValue)
@ -422,7 +422,7 @@ class AsmGen(private val program: Program,
else
out(" ${m.name} = ${asmVariableName((m.value as AddressOf).identifier)}")
}
val asmSubs = statements.filterIsInstance<Subroutine>().filter { it.isAsmSubroutine }
val asmSubs = statements.asSequence().filterIsInstance<Subroutine>().filter { it.isAsmSubroutine }
for(sub in asmSubs) {
val addr = sub.asmAddress
if(addr!=null) {
@ -435,7 +435,7 @@ class AsmGen(private val program: Program,
private fun vardecls2asm(statements: List<Statement>, inBlock: Block?) {
out("\n; non-zeropage variables")
val vars = statements.filterIsInstance<VarDecl>().filter { it.type==VarDeclType.VAR }
val vars = statements.asSequence().filterIsInstance<VarDecl>().filter { it.type==VarDeclType.VAR }
val encodedstringVars = vars
.filter { it.datatype == DataType.STR && shouldActuallyOutputStringVar(it) }

View File

@ -49,7 +49,7 @@ class AstPreprocessor(val program: Program, val errors: IErrorReporter) : AstWal
// move vardecls in Anonymous scope up to the containing subroutine
// and add initialization assignment in its place if needed
val vars = scope.statements.filterIsInstance<VarDecl>()
val vars = scope.statements.asSequence().filterIsInstance<VarDecl>()
val parentscope = scope.definingScope
if(vars.any() && parentscope !== parent) {
val movements = mutableListOf<IAstModification>()

View File

@ -21,7 +21,7 @@ internal class AstVariousTransforms(private val program: Program) : AstWalker()
val namesInSub = symbolsInSub.map{ it.first }.toSet()
if(subroutine.asmAddress==null) {
if(!subroutine.isAsmSubroutine && subroutine.parameters.isNotEmpty()) {
val vars = subroutine.statements.filterIsInstance<VarDecl>().map { it.name }.toSet()
val vars = subroutine.statements.asSequence().filterIsInstance<VarDecl>().map { it.name }.toSet()
if(!vars.containsAll(subroutine.parameters.map{it.name})) {
return subroutine.parameters
.filter { it.name !in namesInSub }

View File

@ -31,7 +31,7 @@ internal class StatementReorderer(val program: Program,
val (blocks, other) = module.statements.partition { it is Block }
module.statements = other.asSequence().plus(blocks.sortedBy { (it as Block).address ?: UInt.MAX_VALUE }).toMutableList()
val mainBlock = module.statements.filterIsInstance<Block>().firstOrNull { it.name=="main" }
val mainBlock = module.statements.asSequence().filterIsInstance<Block>().firstOrNull { it.name=="main" }
if(mainBlock!=null && mainBlock.address==null) {
module.statements.remove(mainBlock)
module.statements.add(0, mainBlock)
@ -118,7 +118,7 @@ internal class StatementReorderer(val program: Program,
override fun before(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
if(subroutine.name=="start" && parent is Block) {
if(parent.statements.filterIsInstance<Subroutine>().first().name!="start") {
if(parent.statements.asSequence().filterIsInstance<Subroutine>().first().name!="start") {
return listOf(
IAstModification.Remove(subroutine, parent),
IAstModification.InsertFirst(subroutine, parent)
@ -150,6 +150,7 @@ internal class StatementReorderer(val program: Program,
varsChanges +=
if(stringParamsByNames.isNotEmpty()) {
subroutine.statements
.asSequence()
.filterIsInstance<VarDecl>()
.filter { it.subroutineParameter!=null && it.name in stringParamsByNames }
.map {
@ -166,7 +167,7 @@ internal class StatementReorderer(val program: Program,
IAstModification.ReplaceNode(it, newvar, subroutine)
}
}
else emptyList()
else emptySequence()
}
return modifications + parameterChanges + varsChanges

View File

@ -43,7 +43,7 @@ private fun prepareTestFiles(source: String, optimize: Boolean, target: ICompila
if (target == Cx16Target) {
searchIn.add(0, assumeDirectory(examplesDir, "cx16"))
}
val filepath = searchIn
val filepath = searchIn.asSequence()
.map { it.resolve("$source.p8") }
.map { it.normalize().absolute() }
.map { workingDir.relativize(it) }

View File

@ -403,7 +403,7 @@ class TestOptimization: FunSpec({
"""
val result = compileText(C64Target, optimize=true, src, writeAssembly=false).assertSuccess()
result.program.entrypoint.statements.size shouldBe 7
val alldecls = result.program.entrypoint.allDefinedSymbols
val alldecls = result.program.entrypoint.allDefinedSymbols.toList()
alldecls.map { it.first } shouldBe listOf("unused_but_shared", "usedvar_only_written", "usedvar")
}

View File

@ -97,19 +97,19 @@ class TestAsmGenSymbols: StringSpec({
val sub = program.entrypoint
// local variable
val localvarIdent = sub.statements.filterIsInstance<Assignment>().first { it.value is IdentifierReference }.value as IdentifierReference
val localvarIdent = sub.statements.asSequence().filterIsInstance<Assignment>().first { it.value is IdentifierReference }.value as IdentifierReference
asmgen.asmSymbolName(localvarIdent) shouldBe "localvar"
asmgen.asmVariableName(localvarIdent) shouldBe "localvar"
val localvarIdentScoped = (sub.statements.filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main", "start", "localvar") }.value as AddressOf).identifier
val localvarIdentScoped = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main", "start", "localvar") }.value as AddressOf).identifier
asmgen.asmSymbolName(localvarIdentScoped) shouldBe "main.start.localvar"
asmgen.asmVariableName(localvarIdentScoped) shouldBe "main.start.localvar"
// variable from outer scope (note that for Variables, no scoping prefix symbols are required,
// because they're not outputted as locally scoped symbols for the assembler
val scopedVarIdent = (sub.statements.filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("var_outside") }.value as AddressOf).identifier
val scopedVarIdent = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("var_outside") }.value as AddressOf).identifier
asmgen.asmSymbolName(scopedVarIdent) shouldBe "main.var_outside"
asmgen.asmVariableName(scopedVarIdent) shouldBe "var_outside"
val scopedVarIdentScoped = (sub.statements.filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main", "var_outside") }.value as AddressOf).identifier
val scopedVarIdentScoped = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main", "var_outside") }.value as AddressOf).identifier
asmgen.asmSymbolName(scopedVarIdentScoped) shouldBe "main.var_outside"
asmgen.asmVariableName(scopedVarIdentScoped) shouldBe "main.var_outside"
}
@ -120,24 +120,24 @@ class TestAsmGenSymbols: StringSpec({
val sub = program.entrypoint
// local label
val localLabelIdent = (sub.statements.filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("locallabel") }.value as AddressOf).identifier
val localLabelIdent = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("locallabel") }.value as AddressOf).identifier
asmgen.asmSymbolName(localLabelIdent) shouldBe "_locallabel"
withClue("as a variable it uses different naming rules (no underscore prefix)") {
asmgen.asmVariableName(localLabelIdent) shouldBe "locallabel"
}
val localLabelIdentScoped = (sub.statements.filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main","start","locallabel") }.value as AddressOf).identifier
val localLabelIdentScoped = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main","start","locallabel") }.value as AddressOf).identifier
asmgen.asmSymbolName(localLabelIdentScoped) shouldBe "main.start._locallabel"
withClue("as a variable it uses different naming rules (no underscore prefix)") {
asmgen.asmVariableName(localLabelIdentScoped) shouldBe "main.start.locallabel"
}
// label from outer scope needs sope prefixes because it is outputted as a locally scoped symbol for the assembler
val scopedLabelIdent = (sub.statements.filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("label_outside") }.value as AddressOf).identifier
val scopedLabelIdent = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("label_outside") }.value as AddressOf).identifier
asmgen.asmSymbolName(scopedLabelIdent) shouldBe "main._label_outside"
withClue("as a variable it uses different naming rules (no underscore prefix)") {
asmgen.asmVariableName(scopedLabelIdent) shouldBe "label_outside"
}
val scopedLabelIdentScoped = (sub.statements.filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main","label_outside") }.value as AddressOf).identifier
val scopedLabelIdentScoped = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main","label_outside") }.value as AddressOf).identifier
asmgen.asmSymbolName(scopedLabelIdentScoped) shouldBe "main._label_outside"
withClue("as a variable it uses different naming rules (no underscore prefix)") {
asmgen.asmVariableName(scopedLabelIdentScoped) shouldBe "main.label_outside"

View File

@ -133,9 +133,9 @@ interface IStatementContainer {
return null
}
val allDefinedSymbols: List<Pair<String, Statement>>
val allDefinedSymbols: Sequence<Pair<String, Statement>>
get() {
return statements.filterIsInstance<INamedStatement>().map { Pair(it.name, it as Statement) }
return statements.asSequence().filterIsInstance<INamedStatement>().map { Pair(it.name, it as Statement) }
}
}