mirror of
https://github.com/irmen/prog8.git
synced 2025-10-08 02:16:58 +00:00
IR: add a unit test for the SSA basic block change
This commit is contained in:
@@ -3,6 +3,8 @@ package prog8tests.vm
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.engine.spec.tempdir
|
||||
import io.kotest.matchers.collections.shouldBeIn
|
||||
import io.kotest.matchers.ints.shouldBeLessThanOrEqual
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
@@ -12,10 +14,7 @@ import prog8.ast.statements.Assignment
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.code.target.Cx16Target
|
||||
import prog8.code.target.VMTarget
|
||||
import prog8.intermediate.IRDataType
|
||||
import prog8.intermediate.IRFileReader
|
||||
import prog8.intermediate.IRSubroutine
|
||||
import prog8.intermediate.Opcode
|
||||
import prog8.intermediate.*
|
||||
import prog8.vm.VmRunner
|
||||
import prog8tests.helpers.ErrorReporterForTests
|
||||
import prog8tests.helpers.compileText
|
||||
@@ -558,4 +557,32 @@ main {
|
||||
}"""
|
||||
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
|
||||
}
|
||||
|
||||
test("SSA basic blocks") {
|
||||
val src= """
|
||||
main {
|
||||
sub start() {
|
||||
func()
|
||||
}
|
||||
|
||||
sub func() {
|
||||
if cx16.r0<10 or cx16.r0>319 {
|
||||
cx16.r1++
|
||||
}
|
||||
}
|
||||
}"""
|
||||
val result = compileText(VMTarget(), false, src, outputDir)!!
|
||||
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
|
||||
val irProgram = IRFileReader().read(virtfile)
|
||||
val func = irProgram.blocks[0].children[1] as IRSubroutine
|
||||
func.label shouldBe "main.func"
|
||||
func.chunks.size shouldBe 11
|
||||
for(chunk in func.chunks) {
|
||||
if(chunk.next == null) {
|
||||
chunk.instructions.last().opcode shouldBeIn OpcodesThatBranchUnconditionally
|
||||
}
|
||||
val branches = chunk.instructions.filter { it.opcode in OpcodesThatEndSSAblock }
|
||||
branches.size shouldBeLessThanOrEqual 1
|
||||
}
|
||||
}
|
||||
})
|
@@ -50,7 +50,6 @@ Future Things and Ideas
|
||||
|
||||
IR/VM
|
||||
-----
|
||||
- TestVMCodegen: add tests for SSA block split/joins/check last instruction to be a valid SSE block ender
|
||||
- is it possible to use LOADFIELD/STOREFIELD instructions even more?
|
||||
- make multiple classes of registers and maybe also categorize by life time , to prepare for better register allocation in the future
|
||||
SYSCALL_ARGS, // Reserved for syscall arguments (r99000-99099, r99100-99199)
|
||||
|
@@ -1,5 +1,11 @@
|
||||
main {
|
||||
sub start() {
|
||||
cx16.r0L= sqrt(cx16.r1)
|
||||
func()
|
||||
}
|
||||
|
||||
sub func() {
|
||||
if cx16.r0<10 or cx16.r0>319 {
|
||||
cx16.r1++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user