ir: fix chunk linkage in optimizer

This commit is contained in:
Irmen de Jong 2022-10-30 23:42:41 +01:00
parent 5b6569d0f9
commit 5efe2b027a
3 changed files with 16 additions and 7 deletions

View File

@ -99,8 +99,11 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
val chunks = mutableListOf<IRCodeChunkBase>() val chunks = mutableListOf<IRCodeChunkBase>()
chunks += sub.chunks[0] chunks += sub.chunks[0]
for(ix in 1 until sub.chunks.size) { for(ix in 1 until sub.chunks.size) {
if(mayJoin(chunks.last(), sub.chunks[ix])) val lastChunk = chunks.last()
chunks.last().instructions += sub.chunks[ix].instructions if(mayJoin(lastChunk, sub.chunks[ix])) {
lastChunk.instructions += sub.chunks[ix].instructions
lastChunk.next = sub.chunks[ix].next
}
else else
chunks += sub.chunks[ix] chunks += sub.chunks[ix]
} }

View File

@ -3,8 +3,6 @@ TODO
For next release For next release
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
- ir: join more codechunks, before ir is written to file
- ir: fix removeWeirdBranches in IR optimizer
- update diagram in technical.rst? - update diagram in technical.rst?
... ...

View File

@ -100,7 +100,7 @@ class IRProgram(val name: String,
// no jump at the end, so link to next chunk (if it exists) // no jump at the end, so link to next chunk (if it exists)
val next = nextChunk() val next = nextChunk()
if(next!=null) { if(next!=null) {
if (next is IRCodeChunk) if (next is IRCodeChunk && chunk.instructions.lastOrNull()?.opcode !in OpcodesThatJump)
chunk.next = next chunk.next = next
else else
throw AssemblyError("code chunk flows into following non-code chunk") throw AssemblyError("code chunk flows into following non-code chunk")
@ -144,8 +144,16 @@ class IRProgram(val name: String,
require(sub.chunks.first().label == sub.name) { "first chunk in subroutine should have sub name as its label" } require(sub.chunks.first().label == sub.name) { "first chunk in subroutine should have sub name as its label" }
} }
sub.chunks.forEach { chunk -> sub.chunks.forEach { chunk ->
if (chunk is IRCodeChunk) if (chunk is IRCodeChunk) {
require(chunk.instructions.isNotEmpty() || chunk.label!=null) require(chunk.instructions.isNotEmpty() || chunk.label != null)
if(chunk.instructions.lastOrNull()?.opcode in OpcodesThatJump)
require(chunk.next == null) { "chunk ending with a jump shouldn't be linked to next" }
else {
// if chunk is NOT the last in the block, it needs to link to next.
val isLast = sub.chunks.last() === chunk
require(isLast || chunk.next != null) { "chunk needs to be linked to next" }
}
}
else else
require(chunk.instructions.isEmpty()) require(chunk.instructions.isEmpty())
chunk.instructions.forEach { chunk.instructions.forEach {