User defined blocks are sorted first, before library blocks. This prioritizes zero page allocation to user code (and makes reading the program easier)

This commit is contained in:
Irmen de Jong 2019-02-01 01:22:27 +01:00
parent 86ff08e854
commit f83b9732ee
5 changed files with 34 additions and 30 deletions

View File

@ -506,11 +506,11 @@ private class GlobalNamespace(override val name: String,
class Block(override val name: String,
val address: Int?,
override var statements: MutableList<IStatement>,
val isInLibrary: Boolean,
override val position: Position) : IStatement, INameScope {
override lateinit var parent: Node
val scopedname: String by lazy { makeScopedName(name).joinToString(".") }
override fun linkParents(parent: Node) {
this.parent = parent
statements.forEach {it.linkParents(this)}
@ -1754,7 +1754,7 @@ class RepeatLoop(var body: AnonymousScope,
/***************** Antlr Extension methods to create AST ****************/
fun prog8Parser.ModuleContext.toAst(name: String, isLibrary: Boolean, importedFrom: Path) : Module =
Module(name, modulestatement().asSequence().map { it.toAst() }.toMutableList(), toPosition(), isLibrary, importedFrom)
Module(name, modulestatement().asSequence().map { it.toAst(isLibrary) }.toMutableList(), toPosition(), isLibrary, importedFrom)
private fun ParserRuleContext.toPosition() : Position {
@ -1768,19 +1768,19 @@ private fun ParserRuleContext.toPosition() : Position {
}
private fun prog8Parser.ModulestatementContext.toAst() : IStatement {
private fun prog8Parser.ModulestatementContext.toAst(isInLibrary: Boolean) : IStatement {
val directive = directive()?.toAst()
if(directive!=null) return directive
val block = block()?.toAst()
val block = block()?.toAst(isInLibrary)
if(block!=null) return block
throw FatalAstException(text)
}
private fun prog8Parser.BlockContext.toAst() : IStatement =
Block(identifier().text, integerliteral()?.toAst()?.number?.toInt(), statement_block().toAst(), toPosition())
private fun prog8Parser.BlockContext.toAst(isInLibrary: Boolean) : IStatement =
Block(identifier().text, integerliteral()?.toAst()?.number?.toInt(), statement_block().toAst(), isInLibrary, toPosition())
private fun prog8Parser.Statement_blockContext.toAst(): MutableList<IStatement> =

View File

@ -33,11 +33,21 @@ private class StatementReorderer(private val namespace: INameScope, private val
val (blocks, other) = module.statements.partition { it is Block }
module.statements = other.asSequence().plus(blocks.sortedBy { (it as Block).address ?: Int.MAX_VALUE }).toMutableList()
// make sure user-defined blocks come BEFORE library blocks, and move the "main" block to the top of everything
val nonLibraryBlocks = module.statements.withIndex()
.filter { it.value is Block && !(it.value as Block).isInLibrary }
.map { it.index to it.value }
.reversed()
for(blocks in nonLibraryBlocks)
module.statements.removeAt(blocks.first)
for(blocks in nonLibraryBlocks)
module.statements.add(0, blocks.second)
val mainBlock = module.statements.single { it is Block && it.name=="main" }
if((mainBlock as Block).address==null) {
module.statements.remove(mainBlock)
module.statements.add(0, mainBlock)
}
val varDecls = module.statements.filterIsInstance<VarDecl>()
module.statements.removeAll(varDecls)
module.statements.addAll(0, varDecls)
@ -46,8 +56,6 @@ private class StatementReorderer(private val namespace: INameScope, private val
module.statements.removeAll(directives)
module.statements.addAll(0, directives)
// TODO make sure user-defined blocks come BEFORE library blocks
sortConstantAssignments(module.statements)
}

View File

@ -31,7 +31,6 @@ Add more compiler optimizations to the existing ones.
- on the final assembly source level
- can the parameter passing to subroutines be optimized to avoid copying?
- make sure user-defined blocks come BEFORE library blocks (this helps zeropage variable allocations)
- subroutines with 1 or 2 byte args (or 1 word arg) should be converted to asm calling convention with the args in A/Y register

View File

@ -4,27 +4,23 @@
sub start() {
foo(1)
foo2(20)
bar(2,3)
baz(3333)
baz(-3333)
myblock2.foo()
myblock3.foo()
}
sub foo(ubyte arg) {
A=arg
}
sub foo2(byte arg) {
A=33
}
sub bar(ubyte arg1, ubyte arg2) {
A=arg1
}
sub baz(word arg) {
A=lsb(arg)
}
}
~ myblock2 {
sub foo() {
A=99
}
}
~ myblock3 {
sub foo() {
A=99
}
}

View File

@ -11,6 +11,7 @@
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/docs/build" />
<excludeFolder url="file://$MODULE_DIR$/gradle" />
<excludeFolder url="file://$MODULE_DIR$/out" />
</content>