mirror of
https://github.com/irmen/prog8.git
synced 2025-02-13 18:31:04 +00:00
IR: report register usage and types in code blocks
This commit is contained in:
parent
056c0a24d9
commit
7b4a82b91a
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 ->
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user