diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt index 462a8f447..58cba81a5 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt @@ -99,8 +99,11 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) { val chunks = mutableListOf() chunks += sub.chunks[0] for(ix in 1 until sub.chunks.size) { - if(mayJoin(chunks.last(), sub.chunks[ix])) - chunks.last().instructions += sub.chunks[ix].instructions + val lastChunk = chunks.last() + if(mayJoin(lastChunk, sub.chunks[ix])) { + lastChunk.instructions += sub.chunks[ix].instructions + lastChunk.next = sub.chunks[ix].next + } else chunks += sub.chunks[ix] } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 933aaf6af..00f8ada95 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- ir: join more codechunks, before ir is written to file -- ir: fix removeWeirdBranches in IR optimizer - update diagram in technical.rst? ... diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index f5f3d1de0..a5f28a83d 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -100,7 +100,7 @@ class IRProgram(val name: String, // no jump at the end, so link to next chunk (if it exists) val next = nextChunk() if(next!=null) { - if (next is IRCodeChunk) + if (next is IRCodeChunk && chunk.instructions.lastOrNull()?.opcode !in OpcodesThatJump) chunk.next = next else 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" } } sub.chunks.forEach { chunk -> - if (chunk is IRCodeChunk) - require(chunk.instructions.isNotEmpty() || chunk.label!=null) + if (chunk is IRCodeChunk) { + 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 require(chunk.instructions.isEmpty()) chunk.instructions.forEach {