IR: report register usage and types in code blocks

This commit is contained in:
Irmen de Jong 2024-12-26 14:57:07 +01:00
parent 056c0a24d9
commit 7b4a82b91a
4 changed files with 50 additions and 9 deletions

View File

@ -54,8 +54,8 @@ Future Things and Ideas
IR/VM
-----
- make a list in the P8IR file of the data type of every used virtual register (it should have 1 unique type assigned to it when it is allocated, and never used for other types) via usedRegisters()
- getting it in shape for code generation...
- getting it in shape for code generation...: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
- addUsedRegistersCounts() doesn't always determine the datatype correctly. For instance with indirect instructions it thinks it still is a byte whereas it is a word (address)
- fix TODO("IR rol/ror on split words array")
- fix "<< in array" / ">> in array"
- implement missing operators in AssignmentGen (array shifts etc)

View File

@ -11,6 +11,7 @@ import java.nio.file.Path
import javax.xml.stream.XMLEventReader
import javax.xml.stream.XMLInputFactory
import javax.xml.stream.XMLStreamException
import javax.xml.stream.events.XMLEvent
import kotlin.io.path.Path
import kotlin.io.path.inputStream
@ -328,14 +329,21 @@ class IRFileReader {
private fun parseCodeChunk(reader: XMLEventReader): IRCodeChunk {
skipText(reader)
val start = reader.nextEvent().asStartElement()
require(start.name.localPart=="CODE") { "missing CODE" }
val next = reader.peek()
val codeStart = reader.nextEvent().asStartElement()
require(codeStart.name.localPart=="CODE") { "missing CODE" }
// now skip <REGS> as it is informational
val regsStart = reader.nextEvent().asStartElement()
require(regsStart.name.localPart=="REGS") { "missing REGS" }
require(reader.nextEvent().isCharacters)
require(reader.nextEvent().isEndElement)
var next = reader.peek()
if(next.isStartElement && next.asStartElement().name.localPart=="P8SRC") {
reader.nextEvent() // skip the P8SRC node
while(!reader.nextEvent().isEndElement) { /* skip until end of P8SRC node */ }
}
val label = start.attributes.asSequence().singleOrNull { it.name.localPart == "LABEL" }?.value?.ifBlank { null }
val label = codeStart.attributes.asSequence().singleOrNull { it.name.localPart == "LABEL" }?.value?.ifBlank { null }
val text = readText(reader).trim()
val chunk = IRCodeChunk(label, null)
if(text.isNotBlank()) {
@ -353,6 +361,7 @@ class IRFileReader {
}
}
}
require(reader.nextEvent().isEndElement)
return chunk
}

View File

@ -130,9 +130,41 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
}
private fun writeCodeChunk(chunk: IRCodeChunk) {
val usedRegs = chunk.usedRegisters()
val regs = StringBuilder()
if(usedRegs.readRegs.any() || usedRegs.writeRegs.any()) {
regs.append("\nINT REGS:\n")
if (usedRegs.readRegs.any())
regs.append(" read: ${usedRegs.readRegs.toSortedMap().map { (reg, amount) -> "r$reg=${amount}" }}\n")
if (usedRegs.writeRegs.any())
regs.append(" write: ${usedRegs.writeRegs.toSortedMap().map { (reg, amount) -> "r$reg=${amount}" }}\n")
regs.append(" types:\n")
for ((regnum, types) in usedRegs.regsTypes.toSortedMap()) {
regs.append(" r$regnum -> $types")
if (types.size > 1) {
regs.append(" !!!! more than one type !!!!\n")
println("Detected multi-type register usage: $regnum->$types in ${chunk.label} at ${chunk.sourceLinesPositions.firstOrNull()}")
}
else
regs.append("\n")
}
}
if(usedRegs.readFpRegs.any() || usedRegs.writeFpRegs.any()) {
regs.append("\nFP REGS:\n")
if(usedRegs.readFpRegs.any())
regs.append(" read: ${usedRegs.readFpRegs.toSortedMap().map { (reg, amount) -> "fr$reg=${amount}" }}\n")
if(usedRegs.writeFpRegs.any())
regs.append(" write: ${usedRegs.writeRegs.toSortedMap().map { (reg, amount) -> "fr$reg=${amount}" }}\n")
}
xml.writeStartElement("CODE")
chunk.label?.let { xml.writeAttribute("LABEL", chunk.label) }
// xml.writeAttribute("used-registers", chunk.usedRegisters().toString())
xml.writeStartElement("REGS")
xml.writeCData(regs.toString())
xml.writeEndElement()
writeSourcelines(xml, chunk)
xml.writeCharacters("\n")
chunk.instructions.forEach { instr ->

View File

@ -70,7 +70,7 @@ ubyte main.thing=42
</MEMORYSLABS>
<INITGLOBALS>
<CODE>
<CODE><REGS>dummy</REGS>
load.b r1,42
</CODE>
</INITGLOBALS>
@ -79,7 +79,7 @@ load.b r1,42
<SUB NAME="main.start" RETURNTYPE="" POS="[examples/test.p8: line 4 col 6-8]">
<PARAMS>
</PARAMS>
<CODE LABEL="main.start">
<CODE LABEL="main.start"><REGS>dummy</REGS>
return
</CODE>
</SUB>
@ -93,7 +93,7 @@ uword sys.wait.jiffies
<ASM LABEL="sys.wait" IR="true" POS="[library:/prog8lib/virtual/syslib.p8: line 17 col 10-13]">
loadm.w r0,sys.wait.jiffies
</ASM>
<CODE>
<CODE><REGS>dummy</REGS>
return
</CODE>
</SUB>