sorting aligned vars to shrink prg size

This commit is contained in:
Irmen de Jong 2024-10-26 18:33:51 +02:00
parent 1cd754f05d
commit 9317cf8a35
4 changed files with 122 additions and 31 deletions

View File

@ -587,7 +587,16 @@ internal class ProgramAndVarsGen(
if(varsNoInit.isNotEmpty()) { if(varsNoInit.isNotEmpty()) {
asmgen.out("; non-zeropage variables") asmgen.out("; non-zeropage variables")
asmgen.out(" .section BSS") asmgen.out(" .section BSS")
varsNoInit.sortedWith(compareBy<StStaticVariable> { it.name }.thenBy { it.dt }).forEach { val wordAligned = varsNoInit.filter { it.align==PtVariable.Alignment.WORD }
val pageAligned = varsNoInit.filter { it.align==PtVariable.Alignment.PAGE }
val notAligned = varsNoInit.filter { it.align==PtVariable.Alignment.NONE }
notAligned.sortedWith(compareBy<StStaticVariable> { it.name }.thenBy { it.dt }).forEach {
uninitializedVariable2asm(it)
}
wordAligned.sortedWith(compareBy<StStaticVariable> { it.name }.thenBy { it.dt }).forEach {
uninitializedVariable2asm(it)
}
pageAligned.sortedWith(compareBy<StStaticVariable> { it.name }.thenBy { it.dt }).forEach {
uninitializedVariable2asm(it) uninitializedVariable2asm(it)
} }
asmgen.out(" .send BSS") asmgen.out(" .send BSS")
@ -596,7 +605,11 @@ internal class ProgramAndVarsGen(
if(varsWithInit.isNotEmpty()) { if(varsWithInit.isNotEmpty()) {
asmgen.out("; non-zeropage variables with init value") asmgen.out("; non-zeropage variables with init value")
val (stringvars, othervars) = varsWithInit.sortedBy { it.name }.partition { it.dt == DataType.STR } val (stringvars, othervars) = varsWithInit.sortedBy { it.name }.partition { it.dt == DataType.STR }
stringvars.forEach {
val stringsWordAligned = stringvars.filter { it.align==PtVariable.Alignment.WORD }
val stringsPageAligned = stringvars.filter { it.align==PtVariable.Alignment.PAGE }
val stringsNotAligned = stringvars.filter { it.align==PtVariable.Alignment.NONE }
stringsNotAligned.forEach {
outputStringvar( outputStringvar(
it.name, it.name,
it.align, it.align,
@ -604,7 +617,33 @@ internal class ProgramAndVarsGen(
it.initializationStringValue!!.first it.initializationStringValue!!.first
) )
} }
othervars.sortedBy { it.type }.forEach { stringsWordAligned.forEach {
outputStringvar(
it.name,
it.align,
it.initializationStringValue!!.second,
it.initializationStringValue!!.first
)
}
stringsPageAligned.forEach {
outputStringvar(
it.name,
it.align,
it.initializationStringValue!!.second,
it.initializationStringValue!!.first
)
}
val wordAligned = othervars.filter { it.align==PtVariable.Alignment.WORD }
val pageAligned = othervars.filter { it.align==PtVariable.Alignment.PAGE }
val notAligned = othervars.filter { it.align==PtVariable.Alignment.NONE }
notAligned.sortedBy { it.type }.forEach {
staticVariable2asm(it)
}
wordAligned.sortedBy { it.type }.forEach {
staticVariable2asm(it)
}
pageAligned.sortedBy { it.type }.forEach {
staticVariable2asm(it) staticVariable2asm(it)
} }
} }
@ -667,7 +706,9 @@ internal class ProgramAndVarsGen(
DataType.STR -> { DataType.STR -> {
throw AssemblyError("all string vars should have been interned into prog") throw AssemblyError("all string vars should have been interned into prog")
} }
in ArrayDatatypes -> arrayVariable2asm(variable.name, variable.dt, variable.align, variable.initializationArrayValue, variable.length) in ArrayDatatypes -> {
arrayVariable2asm(variable.name, variable.dt, variable.align, variable.initializationArrayValue, variable.length)
}
else -> { else -> {
throw AssemblyError("weird dt") throw AssemblyError("weird dt")
} }

View File

@ -1,8 +1,7 @@
TODO TODO
==== ====
- are uninitialized (bss) variables correctly @aligned now? (%option align docs say they're not, but maybe the new @align tag fixes this too) - add docs for @align. Note: uninitialized (bss) variables are also correctly aligned (%option align docs say they're not, but that is fixed)
- aligned vars codegen: sort to do all word alignments first then the page alignments
- what to use to align a label ? (%align $100 ?) to support aligned asmincludes for example. - what to use to align a label ? (%align $100 ?) to support aligned asmincludes for example.
- remove %option align_xxx ? (block level alignment, as we now have individual variable alignments) - remove %option align_xxx ? (block level alignment, as we now have individual variable alignments)
@ -44,6 +43,7 @@ Future Things and Ideas
- ir: add more optimizations in IRPeepholeOptimizer - ir: add more optimizations in IRPeepholeOptimizer
- ir: the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line. - ir: the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line.
maybe another representation is needed once actual codegeneration is done from the IR...? maybe another representation is needed once actual codegeneration is done from the IR...?
- ir: split word arrays, both _msb and _lsb arrays are tagged with an alignment. This is not what's intended; only the one put in memory first should be aligned (the other one should follow straight after it)
- ir: getting it in shape for code generation... - ir: getting it in shape for code generation...
- ir: make optimizeBitTest work for IR too to use the BIT instruction? - ir: make optimizeBitTest work for IR too to use the BIT instruction?
- ir: make sure that a 6502 codegen based off the IR, still generates BIT instructions when testing bit 7 or 6 of a byte var. - ir: make sure that a 6502 codegen based off the IR, still generates BIT instructions when testing bit 7 or 6 of a byte var.

View File

@ -1,20 +1,45 @@
%option no_sysinit %option no_sysinit
%zeropage basicsafe %zeropage dontuse
main { main {
sub start() { sub start() {
str @alignword @shared name = "wordaligned" str @alignword @shared name1 = "abc123456789"
str @alignpage @shared @nozp name2 = "pagealigned" str @alignpage @shared name2 = "def123456789"
ubyte[20] @alignword @shared array1 str @alignword @shared @nozp name3 = "ghi123456789"
ubyte[20] @alignword @shared array2 str @alignword @shared @nozp name4 = "jkl123456789"
ubyte[20] @alignpage @shared array3 ubyte[9] @alignword @shared array1
ubyte[20] @alignpage @shared array4 ubyte[9] @alignword @shared array2
ubyte[] @alignword @shared array5 = [1,2,3,4] ubyte[9] @alignpage @shared array3
ubyte[] @alignword @shared array6 = [1,2,3,4] ubyte[9] @alignword @shared array4
ubyte[] @alignpage @shared array7 = [1,2,3,4] ubyte[9] @alignword @shared array5
ubyte[] @alignpage @shared array8 = [1,2,3,4] ubyte[9] @alignword @shared array6
uword[20] @alignword @split @shared array9 ubyte[9] @alignword @shared array7
uword[] @alignword @split @shared array10 = [1111,2222,3333,4444] ubyte[9] @alignword @shared array8
ubyte[] @alignword @shared array9 = [1,2,3]
ubyte[] @alignword @shared array10 = [1,2,3]
ubyte[] @alignpage @shared array11 = [1,2,3]
ubyte[] @alignpage @shared array12 = [1,2,3]
ubyte[] @alignword @shared array13 = [1,2,3]
ubyte[] @alignword @shared array14 = [1,2,3]
ubyte[] @alignpage @shared array15 = [1,2,3]
ubyte[] @alignpage @shared array16 = [1,2,3]
uword[3] @alignword @split @shared array17
uword[] @alignword @split @shared array18 = [1111,2222,3333]
array9[2]++
array10[2]++
array11[2]++
array12[2]++
array13[2]++
array14[2]++
array15[2]++
array16[2]++
array17[2]++
array18[2]++
name1[2]++
name2[2]++
name3[2]++
name4[2]++
} }
} }

View File

@ -202,12 +202,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
} }
private fun writeVariables() { private fun writeVariables() {
fun writeNoInitVar(variable: IRStStaticVariable) {
val (variablesNoInit, variablesWithInit) = irProgram.st.allVariables().partition { it.uninitialized }
xml.writeStartElement("VARIABLESNOINIT")
xml.writeCharacters("\n")
for (variable in variablesNoInit) {
if(variable.dt in SplitWordArrayTypes) { if(variable.dt in SplitWordArrayTypes) {
// split into 2 ubyte arrays lsb+msb // split into 2 ubyte arrays lsb+msb
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb zp=${variable.zpwish} align=${variable.align}\n") xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb zp=${variable.zpwish} align=${variable.align}\n")
@ -217,12 +212,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
} }
} }
xml.writeEndElement() fun writeVarWithInit(variable: IRStStaticVariable) {
xml.writeCharacters("\n")
xml.writeStartElement("VARIABLESWITHINIT")
xml.writeCharacters("\n")
for (variable in variablesWithInit) {
if(variable.dt in SplitWordArrayTypes) { if(variable.dt in SplitWordArrayTypes) {
val lsbValue: String val lsbValue: String
val msbValue: String val msbValue: String
@ -282,6 +272,41 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
xml.writeCharacters("${variable.typeString} ${variable.name}=$value zp=${variable.zpwish} align=${variable.align}\n") xml.writeCharacters("${variable.typeString} ${variable.name}=$value zp=${variable.zpwish} align=${variable.align}\n")
} }
} }
val (variablesNoInit, variablesWithInit) = irProgram.st.allVariables().partition { it.uninitialized }
xml.writeStartElement("VARIABLESNOINIT")
xml.writeCharacters("\n")
val noinitNotAligned = variablesNoInit.filter { it.align==IRStStaticVariable.Alignment.NONE }
val noinitWordAligned = variablesNoInit.filter { it.align==IRStStaticVariable.Alignment.WORD }
val noinitPageAligned = variablesNoInit.filter { it.align==IRStStaticVariable.Alignment.PAGE }
for (variable in noinitNotAligned) {
writeNoInitVar(variable)
}
for (variable in noinitWordAligned) {
writeNoInitVar(variable)
}
for (variable in noinitPageAligned) {
writeNoInitVar(variable)
}
xml.writeEndElement()
xml.writeCharacters("\n")
xml.writeStartElement("VARIABLESWITHINIT")
xml.writeCharacters("\n")
val initNotAligned = variablesWithInit.filter { it.align==IRStStaticVariable.Alignment.NONE }
val initWordAligned = variablesWithInit.filter { it.align==IRStStaticVariable.Alignment.WORD }
val initPageAligned = variablesWithInit.filter { it.align==IRStStaticVariable.Alignment.PAGE }
for (variable in initNotAligned) {
writeVarWithInit(variable)
}
for (variable in initWordAligned) {
writeVarWithInit(variable)
}
for (variable in initPageAligned) {
writeVarWithInit(variable)
}
xml.writeEndElement() xml.writeEndElement()
xml.writeCharacters("\n") xml.writeCharacters("\n")