reducing dependencies

This commit is contained in:
Irmen de Jong 2022-03-10 21:17:31 +01:00
parent 546a416f7e
commit e7c4bf5ebf
6 changed files with 45 additions and 49 deletions

View File

@ -231,11 +231,11 @@ class AsmGen(internal val program: Program,
} }
CpuRegister.X -> { CpuRegister.X -> {
out(" stx prog8_regsaveX") out(" stx prog8_regsaveX")
allocator.subroutineExtra(scope).usedRegsaveX = true subroutineExtra(scope).usedRegsaveX = true
} }
CpuRegister.Y -> { CpuRegister.Y -> {
out(" sty prog8_regsaveY") out(" sty prog8_regsaveY")
allocator.subroutineExtra(scope).usedRegsaveY = true subroutineExtra(scope).usedRegsaveY = true
} }
} }
} }
@ -727,7 +727,7 @@ $repeatLabel lda $counterVar
private fun createRepeatCounterVar(dt: DataType, preferZeropage: Boolean, stmt: RepeatLoop): String { private fun createRepeatCounterVar(dt: DataType, preferZeropage: Boolean, stmt: RepeatLoop): String {
val scope = stmt.definingSubroutine!! val scope = stmt.definingSubroutine!!
val asmInfo = allocator.subroutineExtra(scope) val asmInfo = subroutineExtra(scope)
var parent = stmt.parent var parent = stmt.parent
while(parent !is ParentSentinel) { while(parent !is ParentSentinel) {
if(parent is RepeatLoop) if(parent is RepeatLoop)
@ -1448,7 +1448,7 @@ $repeatLabel lda $counterVar
beq $jumpIfFalseLabel""") beq $jumpIfFalseLabel""")
} else { } else {
val subroutine = left.definingSubroutine!! val subroutine = left.definingSubroutine!!
allocator.subroutineExtra(subroutine).usedFloatEvalResultVar1 = true subroutineExtra(subroutine).usedFloatEvalResultVar1 = true
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine) assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine)
assignExpressionToRegister(left, RegisterOrPair.FAC1) assignExpressionToRegister(left, RegisterOrPair.FAC1)
out(""" out("""
@ -1493,7 +1493,7 @@ $repeatLabel lda $counterVar
beq $jumpIfFalseLabel""") beq $jumpIfFalseLabel""")
} else { } else {
val subroutine = left.definingSubroutine!! val subroutine = left.definingSubroutine!!
allocator.subroutineExtra(subroutine).usedFloatEvalResultVar1 = true subroutineExtra(subroutine).usedFloatEvalResultVar1 = true
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine) assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine)
assignExpressionToRegister(left, RegisterOrPair.FAC1) assignExpressionToRegister(left, RegisterOrPair.FAC1)
out(""" out("""
@ -1538,7 +1538,7 @@ $repeatLabel lda $counterVar
beq $jumpIfFalseLabel""") beq $jumpIfFalseLabel""")
} else { } else {
val subroutine = left.definingSubroutine!! val subroutine = left.definingSubroutine!!
allocator.subroutineExtra(subroutine).usedFloatEvalResultVar1 = true subroutineExtra(subroutine).usedFloatEvalResultVar1 = true
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine) assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine)
assignExpressionToRegister(left, RegisterOrPair.FAC1) assignExpressionToRegister(left, RegisterOrPair.FAC1)
out(""" out("""
@ -1583,7 +1583,7 @@ $repeatLabel lda $counterVar
beq $jumpIfFalseLabel""") beq $jumpIfFalseLabel""")
} else { } else {
val subroutine = left.definingSubroutine!! val subroutine = left.definingSubroutine!!
allocator.subroutineExtra(subroutine).usedFloatEvalResultVar1 = true subroutineExtra(subroutine).usedFloatEvalResultVar1 = true
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine) assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine)
assignExpressionToRegister(left, RegisterOrPair.FAC1) assignExpressionToRegister(left, RegisterOrPair.FAC1)
out(""" out("""
@ -2523,7 +2523,7 @@ $repeatLabel lda $counterVar
beq $jumpIfFalseLabel""") beq $jumpIfFalseLabel""")
} else { } else {
val subroutine = left.definingSubroutine!! val subroutine = left.definingSubroutine!!
allocator.subroutineExtra(subroutine).usedFloatEvalResultVar1 = true subroutineExtra(subroutine).usedFloatEvalResultVar1 = true
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine) assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine)
assignExpressionToRegister(left, RegisterOrPair.FAC1) assignExpressionToRegister(left, RegisterOrPair.FAC1)
out(""" out("""
@ -2608,7 +2608,7 @@ $repeatLabel lda $counterVar
bne $jumpIfFalseLabel""") bne $jumpIfFalseLabel""")
} else { } else {
val subroutine = left.definingSubroutine!! val subroutine = left.definingSubroutine!!
allocator.subroutineExtra(subroutine).usedFloatEvalResultVar1 = true subroutineExtra(subroutine).usedFloatEvalResultVar1 = true
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine) assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT, subroutine)
assignExpressionToRegister(left, RegisterOrPair.FAC1) assignExpressionToRegister(left, RegisterOrPair.FAC1)
out(""" out("""
@ -3039,4 +3039,34 @@ $repeatLabel lda $counterVar
out(" pha | tya | pha") out(" pha | tya | pha")
} }
} }
private val subroutineExtrasCache = mutableMapOf<Subroutine, SubroutineExtraAsmInfo>()
internal fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
var extra = subroutineExtrasCache[sub]
return if(extra==null) {
extra = SubroutineExtraAsmInfo()
subroutineExtrasCache[sub] = extra
extra
}
else
extra
}
} }
/**
* Contains various attributes that influence the assembly code generator.
* Conceptually it should be part of any INameScope.
* But because the resulting code only creates "real" scopes on a subroutine level,
* it's more consistent to only define these attributes on a Subroutine node.
*/
internal class SubroutineExtraAsmInfo {
var usedRegsaveA = false
var usedRegsaveX = false
var usedRegsaveY = false
var usedFloatEvalResultVar1 = false
var usedFloatEvalResultVar2 = false
val extraVars = mutableListOf<Triple<DataType, String, UInt?>>()
}

View File

@ -1622,7 +1622,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
if(scope==null) if(scope==null)
throw AssemblyError("cannot use float arguments outside of a subroutine scope") throw AssemblyError("cannot use float arguments outside of a subroutine scope")
allocations.subroutineExtra(scope).usedFloatEvalResultVar2 = true asmgen.subroutineExtra(scope).usedFloatEvalResultVar2 = true
val variable = IdentifierReference(listOf(subroutineFloatEvalResultVar2), value.position) val variable = IdentifierReference(listOf(subroutineFloatEvalResultVar2), value.position)
val addr = AddressOf(variable, value.position) val addr = AddressOf(variable, value.position)
addr.linkParents(value) addr.linkParents(value)

View File

@ -331,7 +331,7 @@ internal class ProgramAndVarsGen(
} }
asmgen.out("; variables") asmgen.out("; variables")
val asmGenInfo = allocator.subroutineExtra(sub) val asmGenInfo = asmgen.subroutineExtra(sub)
for((dt, name, addr) in asmGenInfo.extraVars) { for((dt, name, addr) in asmGenInfo.extraVars) {
if(addr!=null) if(addr!=null)
asmgen.out("$name = $addr") asmgen.out("$name = $addr")

View File

@ -2,7 +2,6 @@ package prog8.codegen.cpu6502
import com.github.michaelbull.result.fold import com.github.michaelbull.result.fold
import com.github.michaelbull.result.onSuccess import com.github.michaelbull.result.onSuccess
import prog8.ast.statements.Subroutine
import prog8.compilerinterface.* import prog8.compilerinterface.*
@ -11,7 +10,6 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
private val errors: IErrorReporter) { private val errors: IErrorReporter) {
private val zeropage = options.compTarget.machine.zeropage private val zeropage = options.compTarget.machine.zeropage
private val subroutineExtras = mutableMapOf<Subroutine, SubroutineExtraAsmInfo>()
private val memorySlabsInternal = mutableMapOf<String, Pair<UInt, UInt>>() private val memorySlabsInternal = mutableMapOf<String, Pair<UInt, UInt>>()
internal val memorySlabs: Map<String, Pair<UInt, UInt>> = memorySlabsInternal internal val memorySlabs: Map<String, Pair<UInt, UInt>> = memorySlabsInternal
internal val globalFloatConsts = mutableMapOf<Double, String>() // all float values in the entire program (value -> varname) internal val globalFloatConsts = mutableMapOf<Double, String>() // all float values in the entire program (value -> varname)
@ -29,17 +27,6 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables
internal fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
var extra = subroutineExtras[sub]
return if(extra==null) {
extra = SubroutineExtraAsmInfo()
subroutineExtras[sub] = extra
extra
}
else
extra
}
internal fun getFloatAsmConst(number: Double): String { internal fun getFloatAsmConst(number: Double): String {
val asmName = globalFloatConsts[number] val asmName = globalFloatConsts[number]
if(asmName!=null) if(asmName!=null)
@ -152,21 +139,4 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
in ArrayDatatypes -> variable.arraysize!! in ArrayDatatypes -> variable.arraysize!!
else -> null else -> null
} }
/**
* Cntains various attributes that influence the assembly code generator.
* Conceptually it should be part of any INameScope.
* But because the resulting code only creates "real" scopes on a subroutine level,
* it's more consistent to only define these attributes on a Subroutine node.
*/
internal class SubroutineExtraAsmInfo {
var usedRegsaveA = false
var usedRegsaveX = false
var usedRegsaveY = false
var usedFloatEvalResultVar1 = false
var usedFloatEvalResultVar2 = false
val extraVars = mutableListOf<Triple<DataType, String, UInt?>>()
}
} }

View File

@ -30,7 +30,7 @@ internal class SymbolTableMaker: IAstVisitor {
super.visit(block) super.visit(block)
scopestack.pop() scopestack.pop()
st.add(node) st.add(node)
st.origAstLinks[block] = node // st.origAstLinks[block] = node
} }
override fun visit(subroutine: Subroutine) { override fun visit(subroutine: Subroutine) {
@ -39,7 +39,7 @@ internal class SymbolTableMaker: IAstVisitor {
super.visit(subroutine) super.visit(subroutine)
scopestack.pop() scopestack.pop()
scopestack.peek().add(node) scopestack.peek().add(node)
st.origAstLinks[subroutine] = node // st.origAstLinks[subroutine] = node
} }
override fun visit(decl: VarDecl) { override fun visit(decl: VarDecl) {
@ -57,7 +57,7 @@ internal class SymbolTableMaker: IAstVisitor {
VarDeclType.MEMORY -> StMemVar(decl.name, decl.datatype, (decl.value as NumericLiteral).number.toUInt(), decl.position) VarDeclType.MEMORY -> StMemVar(decl.name, decl.datatype, (decl.value as NumericLiteral).number.toUInt(), decl.position)
} }
scopestack.peek().add(node) scopestack.peek().add(node)
st.origAstLinks[decl] = node // st.origAstLinks[decl] = node
} }
private fun map(zpw: ZeropageWish): StZeropageWish = when(zpw) { private fun map(zpw: ZeropageWish): StZeropageWish = when(zpw) {
@ -83,6 +83,6 @@ internal class SymbolTableMaker: IAstVisitor {
override fun visit(label: Label) { override fun visit(label: Label) {
val node = StNode(label.name, StNodeType.LABEL, label.position) val node = StNode(label.name, StNodeType.LABEL, label.position)
scopestack.peek().add(node) scopestack.peek().add(node)
st.origAstLinks[label] = node // st.origAstLinks[label] = node
} }
} }

View File

@ -1,7 +1,5 @@
package prog8.compilerinterface package prog8.compilerinterface
import prog8.ast.Node
/** /**
* Tree structure containing all symbol definitions in the program * Tree structure containing all symbol definitions in the program
@ -11,8 +9,6 @@ class SymbolTable : StNode("", StNodeType.GLOBAL, Position.DUMMY) {
fun print() = printIndented(0) fun print() = printIndented(0)
override fun printProperties() { } override fun printProperties() { }
val origAstLinks = mutableMapOf<Node, StNode>() // links of the original Ast nodes to the symbol table node.
} }