start using vars instead of callgraph

This commit is contained in:
Irmen de Jong 2022-02-08 03:16:42 +01:00
parent 7d67005709
commit 1903990f30
5 changed files with 50 additions and 47 deletions

View File

@ -42,7 +42,7 @@ internal class ProgramGen(
if(allBlocks.first().name != "main") if(allBlocks.first().name != "main")
throw AssemblyError("first block should be 'main'") throw AssemblyError("first block should be 'main'")
allocation.allocateAllZeropageVariables(options, callGraph) allocation.allocateAllZeropageVariables(options)
if(errors.noErrors()) { if(errors.noErrors()) {
program.allBlocks.forEach { block2asm(it) } program.allBlocks.forEach { block2asm(it) }

View File

@ -4,61 +4,66 @@ import com.github.michaelbull.result.fold
import com.github.michaelbull.result.onSuccess import com.github.michaelbull.result.onSuccess
import prog8.ast.base.ArrayDatatypes import prog8.ast.base.ArrayDatatypes
import prog8.ast.base.DataType import prog8.ast.base.DataType
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.StringLiteralValue import prog8.ast.expressions.StringLiteralValue
import prog8.ast.statements.VarDecl import prog8.ast.statements.VarDecl
import prog8.ast.statements.VarDeclOrigin
import prog8.ast.statements.ZeropageWish import prog8.ast.statements.ZeropageWish
import prog8.compilerinterface.* import prog8.compilerinterface.CompilationOptions
import prog8.compilerinterface.IErrorReporter
import prog8.compilerinterface.IVariablesAndConsts
import prog8.compilerinterface.ZeropageType
internal class VariableAllocation(val vars: IVariablesAndConsts, val errors: IErrorReporter) { internal class VariableAllocation(val vars: IVariablesAndConsts, val errors: IErrorReporter) {
val varsInZeropage = mutableSetOf<VarDecl>() val varsInZeropage = mutableSetOf<VarDecl>()
fun allocateAllZeropageVariables(options: CompilationOptions, callGraph: CallGraph) { fun allocateAllZeropageVariables(options: CompilationOptions) {
if(options.zeropage== ZeropageType.DONTUSE) if(options.zeropage== ZeropageType.DONTUSE)
return return
val zeropage = options.compTarget.machine.zeropage val allVariables = (
// val allVariables = vars.blockVars.asSequence().flatMap { it.value }.map {it.origVar to it.origVar.scopedName} + vars.blockVars.asSequence().flatMap { it.value }.map {it.origVar to it.origVar.scopedName} +
// vars.subroutineVars.asSequence().flatMap { it.value }.map {it.origVar to it.origVar.scopedName} vars.subroutineVars.asSequence().flatMap { it.value }.map {it.origVar to it.origVar.scopedName})
val allVariables = callGraph.allIdentifiers.asSequence() .toList()
.map { it.value } // TODO now some HACKS to get rid of some unused vars in Petaxian - otherwise the executable gets larger than $45e8
.filterIsInstance<VarDecl>() .filterNot { it.second.last() == "tbl" } // TODO HACK -- NOT REALLY NECESSARY, BUT OLD CallGraph DIDN'T CONTAIN IT EITHER
.filter { it.type== VarDeclType.VAR && it.origin!=VarDeclOrigin.SUBROUTINEPARAM } .filterNot { it.second.last() in setOf("retval_interm_w", "retval_interm_b", "retval_interm_w2", "retval_interm_b2") } // TODO HACK TO REMOVE THESE UNUSED VARS
.toSet()
.map { it to it.scopedName } val varsRequiringZp = allVariables
val varsRequiringZp = allVariables.filter { it.first.zeropage== ZeropageWish.REQUIRE_ZEROPAGE } .filter { it.first.zeropage== ZeropageWish.REQUIRE_ZEROPAGE }
val varsPreferringZp = allVariables val varsPreferringZp = allVariables
.filter { it.first.zeropage== ZeropageWish.PREFER_ZEROPAGE } .filter { it.first.zeropage== ZeropageWish.PREFER_ZEROPAGE }
.sortedBy { options.compTarget.memorySize(it.first.datatype) } // allocate the smallest DT first .sortedBy { options.compTarget.memorySize(it.first.datatype) } // allocate the smallest DT first
/*
// OLD CODE CHECKING:
if(true) {
val allVariablesFoundInCallgraph = callGraphForCheck.allIdentifiers.asSequence()
.map { it.value }
.filterIsInstance<VarDecl>()
.filter { it.type == VarDeclType.VAR && it.origin != VarDeclOrigin.SUBROUTINEPARAM }
.map { it.name to it.position }
.toSet()
val newAllVars = (vars.blockVars.flatMap { it.value }
.map { it.name to it.position } + vars.subroutineVars.flatMap { it.value }
.map { it.name to it.position }).toSet()
val extraVarsInCallgraph = allVariablesFoundInCallgraph - newAllVars
val extraVarsInNew = newAllVars - allVariablesFoundInCallgraph
val allVarsFromCallgraph = allVariables.map { it.first.name to it.first.position }.toSet() if (extraVarsInCallgraph.any() || extraVarsInNew.any()) {
val altAllVars = (vars.blockVars.flatMap { it.value }.map {it.name to it.position} + vars.subroutineVars.flatMap { it.value }.map {it.name to it.position}).toSet() println("EXTRA VARS IN CALLGRAPH: ${extraVarsInCallgraph.size}")
val extraVarsInCallgraph = allVarsFromCallgraph - altAllVars extraVarsInCallgraph.forEach {
val extraVarsInNew = altAllVars - allVarsFromCallgraph println(" $it")
}
if(extraVarsInCallgraph.any() || extraVarsInNew.any()) { println("EXTRA VARS IN VARIABLESOBJ: ${extraVarsInNew.size}")
println("EXTRA VARS IN CALLGRAPH: ${extraVarsInCallgraph.size}") extraVarsInNew.forEach {
extraVarsInCallgraph.forEach { println(" $it")
println(" $it") }
//TODO("fix differences")
} }
println("EXTRA VARS IN VARIABLESOBJ: ${extraVarsInNew.size}")
extraVarsInNew.forEach {
println(" $it")
}
// TODO("fix differences")
} }
*/
val altTotalNumVars = vars.blockVars.flatMap { it.value }.size + vars.subroutineVars.flatMap { it.value }.size val zeropage = options.compTarget.machine.zeropage
val altVarsRequiringZpBlocks = vars.blockVars.flatMap { it.value }.filter { it.zp==ZeropageWish.REQUIRE_ZEROPAGE }
val altVarsRequiringZpSubs = vars.subroutineVars.flatMap { it.value }.filter { it.zp==ZeropageWish.REQUIRE_ZEROPAGE }
val altTotalZpVars = altVarsRequiringZpBlocks.size + altVarsRequiringZpSubs.size
val altVarsPreferringZpBlocks = vars.blockVars.flatMap { it.value }.filter { it.zp==ZeropageWish.PREFER_ZEROPAGE }
val altVarsPreferringZpSubs = vars.subroutineVars.flatMap { it.value }.filter { it.zp==ZeropageWish.PREFER_ZEROPAGE }
val altTotalPrefZpVars = altVarsPreferringZpBlocks.size + altVarsPreferringZpSubs.size
for ((vardecl, scopedname) in varsRequiringZp) { for ((vardecl, scopedname) in varsRequiringZp) {
val numElements: Int? = when(vardecl.datatype) { val numElements: Int? = when(vardecl.datatype) {

View File

@ -7,7 +7,7 @@ conv {
; ----- number conversions to decimal strings ---- ; ----- number conversions to decimal strings ----
str string_out = "????????????????" ; result buffer for the string conversion routines str @shared string_out = "????????????????" ; result buffer for the string conversion routines
asmsub str_ub0 (ubyte value @ A) clobbers(A,Y) { asmsub str_ub0 (ubyte value @ A) clobbers(A,Y) {
; ---- convert the ubyte in A in decimal string form, with left padding 0s (3 positions total) ; ---- convert the ubyte in A in decimal string form, with left padding 0s (3 positions total)

View File

@ -8,12 +8,12 @@ prog8_lib {
; to store intermediary expression results for return values: ; to store intermediary expression results for return values:
; NOTE: these variables can be used in the StatementReorderer and StatementOptimizer ; NOTE: these variables can be used in the StatementReorderer and StatementOptimizer
uword @zp @shared retval_interm_uw uword @zp retval_interm_uw
word @zp @shared retval_interm_w word @zp retval_interm_w
ubyte @zp @shared retval_interm_ub ubyte @zp retval_interm_ub
byte @zp @shared retval_interm_b byte @zp retval_interm_b
word @shared retval_interm_w2 word retval_interm_w2
byte @shared retval_interm_b2 byte retval_interm_b2
; prog8 "hooks" to be able to access the temporary scratch variables ; prog8 "hooks" to be able to access the temporary scratch variables
; YOU SHOULD NOT USE THESE IN USER CODE - THESE ARE MEANT FOR INTERNAL COMPILER USE ; YOU SHOULD NOT USE THESE IN USER CODE - THESE ARE MEANT FOR INTERNAL COMPILER USE

View File

@ -681,8 +681,6 @@ galaxy {
} }
planet { planet {
%option force_output
str[] species_sizes = ["Large", "Fierce", "Small"] str[] species_sizes = ["Large", "Fierce", "Small"]
str[] species_colors = ["Green", "Red", "Yellow", "Blue", "Black", "Harmless"] str[] species_colors = ["Green", "Red", "Yellow", "Blue", "Black", "Harmless"]
str[] species_looks = ["Slimy", "Bug-Eyed", "Horned", "Bony", "Fat", "Furry"] str[] species_looks = ["Slimy", "Bug-Eyed", "Horned", "Bony", "Fat", "Furry"]
@ -728,7 +726,7 @@ planet {
str[] wordsA3 = ["ice", "mud", "Zero-G", "vacuum", "\xB1 ultra"] str[] wordsA3 = ["ice", "mud", "Zero-G", "vacuum", "\xB1 ultra"]
str[] wordsA4 = ["hockey", "cricket", "karate", "polo", "tennis"] str[] wordsA4 = ["hockey", "cricket", "karate", "polo", "tennis"]
uword[] wordlists = [ uword[] @shared wordlists = [
words81, words82, words83, words84, words85, words86, words87, words88, words81, words82, words83, words84, words85, words86, words87, words88,
words89, words8A, words8B, words8C, words8D, words8E, words8F, words90, words89, words8A, words8B, words8C, words8D, words8E, words8F, words90,
words91, words92, words93, words94, words95, words96, words97, words98, words91, words92, words93, words94, words95, words96, words97, words98,