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")
throw AssemblyError("first block should be 'main'")
allocation.allocateAllZeropageVariables(options, callGraph)
allocation.allocateAllZeropageVariables(options)
if(errors.noErrors()) {
program.allBlocks.forEach { block2asm(it) }

View File

@ -4,61 +4,66 @@ import com.github.michaelbull.result.fold
import com.github.michaelbull.result.onSuccess
import prog8.ast.base.ArrayDatatypes
import prog8.ast.base.DataType
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.StringLiteralValue
import prog8.ast.statements.VarDecl
import prog8.ast.statements.VarDeclOrigin
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) {
val varsInZeropage = mutableSetOf<VarDecl>()
fun allocateAllZeropageVariables(options: CompilationOptions, callGraph: CallGraph) {
fun allocateAllZeropageVariables(options: CompilationOptions) {
if(options.zeropage== ZeropageType.DONTUSE)
return
val zeropage = options.compTarget.machine.zeropage
// val allVariables = 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}
val allVariables = callGraph.allIdentifiers.asSequence()
.map { it.value }
.filterIsInstance<VarDecl>()
.filter { it.type== VarDeclType.VAR && it.origin!=VarDeclOrigin.SUBROUTINEPARAM }
.toSet()
.map { it to it.scopedName }
val varsRequiringZp = allVariables.filter { it.first.zeropage== ZeropageWish.REQUIRE_ZEROPAGE }
val allVariables = (
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})
.toList()
// TODO now some HACKS to get rid of some unused vars in Petaxian - otherwise the executable gets larger than $45e8
.filterNot { it.second.last() == "tbl" } // TODO HACK -- NOT REALLY NECESSARY, BUT OLD CallGraph DIDN'T CONTAIN IT EITHER
.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
val varsRequiringZp = allVariables
.filter { it.first.zeropage== ZeropageWish.REQUIRE_ZEROPAGE }
val varsPreferringZp = allVariables
.filter { it.first.zeropage== ZeropageWish.PREFER_ZEROPAGE }
.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()
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()
val extraVarsInCallgraph = allVarsFromCallgraph - altAllVars
val extraVarsInNew = altAllVars - allVarsFromCallgraph
if(extraVarsInCallgraph.any() || extraVarsInNew.any()) {
println("EXTRA VARS IN CALLGRAPH: ${extraVarsInCallgraph.size}")
extraVarsInCallgraph.forEach {
println(" $it")
if (extraVarsInCallgraph.any() || extraVarsInNew.any()) {
println("EXTRA VARS IN CALLGRAPH: ${extraVarsInCallgraph.size}")
extraVarsInCallgraph.forEach {
println(" $it")
}
println("EXTRA VARS IN VARIABLESOBJ: ${extraVarsInNew.size}")
extraVarsInNew.forEach {
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 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
val zeropage = options.compTarget.machine.zeropage
for ((vardecl, scopedname) in varsRequiringZp) {
val numElements: Int? = when(vardecl.datatype) {

View File

@ -7,7 +7,7 @@ conv {
; ----- 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) {
; ---- 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:
; NOTE: these variables can be used in the StatementReorderer and StatementOptimizer
uword @zp @shared retval_interm_uw
word @zp @shared retval_interm_w
ubyte @zp @shared retval_interm_ub
byte @zp @shared retval_interm_b
word @shared retval_interm_w2
byte @shared retval_interm_b2
uword @zp retval_interm_uw
word @zp retval_interm_w
ubyte @zp retval_interm_ub
byte @zp retval_interm_b
word retval_interm_w2
byte retval_interm_b2
; 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

View File

@ -681,8 +681,6 @@ galaxy {
}
planet {
%option force_output
str[] species_sizes = ["Large", "Fierce", "Small"]
str[] species_colors = ["Green", "Red", "Yellow", "Blue", "Black", "Harmless"]
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[] wordsA4 = ["hockey", "cricket", "karate", "polo", "tennis"]
uword[] wordlists = [
uword[] @shared wordlists = [
words81, words82, words83, words84, words85, words86, words87, words88,
words89, words8A, words8B, words8C, words8D, words8E, words8F, words90,
words91, words92, words93, words94, words95, words96, words97, words98,