mirror of
https://github.com/irmen/prog8.git
synced 2026-10-24 18:02:40 +00:00
394 lines
23 KiB
Kotlin
394 lines
23 KiB
Kotlin
package prog8tests.compiler
|
|
|
|
import io.kotest.core.spec.style.FunSpec
|
|
import io.kotest.engine.concurrency.TestExecutionMode
|
|
import io.kotest.engine.spec.tempdir
|
|
import io.kotest.matchers.shouldBe
|
|
import io.kotest.matchers.shouldNotBe
|
|
import prog8.code.core.ICompilationTarget
|
|
import prog8.code.core.OutputFiles
|
|
import prog8.code.target.*
|
|
import prog8.compiler.CompilationResult
|
|
import prog8.compiler.CompilerArguments
|
|
import prog8.compiler.compileProgram
|
|
import prog8tests.helpers.assumeDirectory
|
|
import prog8tests.helpers.cartesianProduct
|
|
import prog8tests.helpers.workingDir
|
|
import java.nio.file.Files
|
|
import java.nio.file.Path
|
|
import kotlin.io.path.exists
|
|
|
|
|
|
/**
|
|
* ATTENTION: this is just kludge!
|
|
* They are not really unit tests, but rather tests of the whole process,
|
|
* from source file loading all the way through to running 64tass.
|
|
*
|
|
* IMPORTANT: The file size checks (cx16SizeOptimized, cx16SizeUnoptimized, etc.) are FRAGILE.
|
|
* These tests should be SKIPPED during regular test runs.
|
|
* Only run these tests explicitly when you have INTENTIONALLY changed the code generator
|
|
* and need to update the expected file sizes ON USER REQUEST.
|
|
* To skip these tests during normal development, do NOT run tests with "TestCompilerOnExamples" in the name.
|
|
* To explicitly run these tests to update expected values:
|
|
* gradle :compiler:test --tests "prog8tests.compiler.TestCompilerOnExamplesCx16"
|
|
*/
|
|
|
|
/**
|
|
* Data class to hold example name and expected output file sizes per target and optimization setting.
|
|
* A size value of 0 means skip the size check for that configuration.
|
|
*/
|
|
private data class ExampleSizes(
|
|
val name: String,
|
|
val c64SizeOptimized: Int = 0,
|
|
val c64SizeUnoptimized: Int = 0,
|
|
val cx16SizeOptimized: Int = 0,
|
|
val cx16SizeUnoptimized: Int = 0,
|
|
val pet32SizeOptimized: Int = 0,
|
|
val pet32SizeUnoptimized: Int = 0,
|
|
val virtualInstrCountOptimized: Int = 0,
|
|
val virtualInstrCountUnoptimized: Int = 0,
|
|
val virtualRegCountOptimized: Int = 0,
|
|
val virtualRegCountUnoptimized: Int = 0
|
|
)
|
|
|
|
private val examplesDir = assumeDirectory(workingDir, "../examples")
|
|
|
|
private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilationTarget, outputDir: Path): CompilationResult? {
|
|
val args = CompilerArguments(
|
|
filepath,
|
|
optimize,
|
|
writeAssembly = true,
|
|
warnSymbolShadowing = false,
|
|
warnImplicitTypeCasts= false,
|
|
quietAll = true,
|
|
quietAssembler = true,
|
|
showTimings = false,
|
|
asmListfile = false,
|
|
includeSourcelines = true,
|
|
newCodegen = false,
|
|
dumpVariables = false,
|
|
dumpSymbols = false,
|
|
varsHighBank = null,
|
|
varsGolden = false,
|
|
varsAddress = null,
|
|
compilationTarget = target.name,
|
|
breakpointCpuInstruction = null,
|
|
printAst1 = false,
|
|
printAst2 = false,
|
|
ignoreFootguns = false,
|
|
profilingInstrumentation = false,
|
|
symbolDefs = emptyMap(),
|
|
outputDir = outputDir
|
|
)
|
|
return compileProgram(args)
|
|
}
|
|
|
|
private fun prepareTestFiles(source: String, optimize: Boolean, target: ICompilationTarget): Pair<String, Path> {
|
|
val searchIn = mutableListOf(examplesDir)
|
|
when (target) {
|
|
is C64Target -> searchIn.add(0, assumeDirectory(examplesDir, "c64"))
|
|
is Cx16Target -> searchIn.add(0, assumeDirectory(examplesDir, "cx16"))
|
|
is VMTarget -> searchIn.add(0, assumeDirectory(examplesDir, "virtual"))
|
|
is C128Target -> searchIn.add(0, assumeDirectory(examplesDir, "c128"))
|
|
is PETTarget -> searchIn.add(0, assumeDirectory(examplesDir, "pet"))
|
|
}
|
|
val filepath = searchIn.asSequence()
|
|
.map { it.resolve("$source.p8") }
|
|
.map { it.normalize() }
|
|
.map { workingDir.relativize(it) }
|
|
.first { it.exists() }
|
|
val displayName = "${examplesDir.relativize(filepath)}: ${target.name}, optimize=$optimize"
|
|
return Pair(displayName, filepath)
|
|
}
|
|
|
|
/**
|
|
* Verifies the size of the compiled output file (.prg or .p8ir) against an expected value.
|
|
* This helps detect any size changes in the compiler output - both increases (code bloat)
|
|
* and decreases (possible broken optimization or missing code).
|
|
* A small tolerance of ±5 bytes is allowed for minor non-deterministic variations.
|
|
*/
|
|
private fun verifyOutputFileSize(result: CompilationResult, expectedSize: Int) {
|
|
val outputFile = OutputFiles.of(result.compilationOptions, result.compilerAst.name).programFile
|
|
val actualSize = Files.size(outputFile).toInt()
|
|
val tolerance = 5 // Allow ±5 bytes for minor non-deterministic variations
|
|
if (actualSize < expectedSize - tolerance || actualSize > expectedSize + tolerance) {
|
|
actualSize shouldBe expectedSize
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verifies the IR instruction count of the compiled .p8ir file against an expected value.
|
|
* This is a stable metric that doesn't change based on source position comments.
|
|
* A small tolerance of ±5 instructions is allowed for minor non-deterministic variations.
|
|
*/
|
|
private fun verifyIrInstructionCount(result: CompilationResult, expectedCount: Int) {
|
|
val actualCount = result.irInstructionCount
|
|
val tolerance = 5 // Allow ±5 instructions for minor non-deterministic variations
|
|
if (actualCount < expectedCount - tolerance || actualCount > expectedCount + tolerance) {
|
|
actualCount shouldBe expectedCount
|
|
}
|
|
}
|
|
|
|
private fun verifyIrRegisterCount(result: CompilationResult, expectedCount: Int) {
|
|
val actualCount = result.irRegisterCount
|
|
val tolerance = 5 // Allow ±5 registers for minor non-deterministic variations
|
|
if (actualCount < expectedCount - tolerance || actualCount > expectedCount + tolerance) {
|
|
actualCount shouldBe expectedCount
|
|
}
|
|
}
|
|
|
|
|
|
class TestCompilerOnExamplesC64: FunSpec({
|
|
|
|
this.blockingTest = true
|
|
this.testExecutionMode = TestExecutionMode.LimitedConcurrency(kotlin.math.max(1, Runtime.getRuntime().availableProcessors()/2))
|
|
|
|
val onlyC64 = cartesianProduct(
|
|
listOf(
|
|
ExampleSizes("balloonflight", c64SizeOptimized=1674, c64SizeUnoptimized=3481),
|
|
ExampleSizes("banking", c64SizeOptimized=680, c64SizeUnoptimized=1356),
|
|
ExampleSizes("bdmusic-irq", c64SizeOptimized=1001, c64SizeUnoptimized=1019),
|
|
ExampleSizes("bdmusic", c64SizeOptimized=938, c64SizeUnoptimized=1011),
|
|
ExampleSizes("charset", c64SizeOptimized=835, c64SizeUnoptimized=860),
|
|
ExampleSizes("cube3d-sprites", c64SizeOptimized=2846, c64SizeUnoptimized=4075),
|
|
ExampleSizes("fileselector", c64SizeOptimized=3523, c64SizeUnoptimized=4510),
|
|
ExampleSizes("library/main", c64SizeOptimized=321, c64SizeUnoptimized=1147),
|
|
ExampleSizes("multiplexer", c64SizeOptimized=1987, c64SizeUnoptimized=3344),
|
|
ExampleSizes("petswirl", c64SizeOptimized=1121, c64SizeUnoptimized=2435),
|
|
ExampleSizes("plasma", c64SizeOptimized=1532, c64SizeUnoptimized=3085),
|
|
ExampleSizes("rasterbars", c64SizeOptimized=776, c64SizeUnoptimized=2319),
|
|
ExampleSizes("simplemultiplexer", c64SizeOptimized=843, c64SizeUnoptimized=900),
|
|
ExampleSizes("sprites", c64SizeOptimized=915, c64SizeUnoptimized=2772),
|
|
ExampleSizes("starfield", c64SizeOptimized=737, c64SizeUnoptimized=758),
|
|
ExampleSizes("turtle-gfx", c64SizeOptimized=2701, c64SizeUnoptimized=2812),
|
|
ExampleSizes("wizzine", c64SizeOptimized=1063, c64SizeUnoptimized=2653),
|
|
// boingball, cube3d, tehtriz are in BothC64andCx16
|
|
),
|
|
listOf(false, true)
|
|
)
|
|
|
|
val target = C64Target()
|
|
onlyC64.forEach { (params, optimize) ->
|
|
val prep = prepareTestFiles(params.name, optimize, target)
|
|
test(prep.first) {
|
|
val testOutputDir = tempdir().toPath()
|
|
val filepath = prep.second
|
|
val expectedSize = if (optimize) params.c64SizeOptimized else params.c64SizeUnoptimized
|
|
val result = compileTheThing(filepath, optimize, target, testOutputDir)
|
|
result shouldNotBe null
|
|
if (expectedSize > 0) {
|
|
verifyOutputFileSize(result!!, expectedSize)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
class TestCompilerOnExamplesCx16: FunSpec({
|
|
|
|
this.blockingTest = true
|
|
this.testExecutionMode = TestExecutionMode.LimitedConcurrency(kotlin.math.max(1, Runtime.getRuntime().availableProcessors()/2))
|
|
|
|
val onlyCx16 = cartesianProduct(
|
|
listOf(
|
|
ExampleSizes("vtui/testvtui", cx16SizeOptimized=3041, cx16SizeUnoptimized=3041),
|
|
ExampleSizes("pcmaudio/play-adpcm", cx16SizeOptimized=37714, cx16SizeUnoptimized=38170),
|
|
ExampleSizes("pcmaudio/stream-wav", cx16SizeOptimized=8026, cx16SizeUnoptimized=10081),
|
|
ExampleSizes("pcmaudio/stream-simple-aflow", cx16SizeOptimized=1842, cx16SizeUnoptimized=3612),
|
|
ExampleSizes("pcmaudio/stream-simple-poll", cx16SizeOptimized=1556, cx16SizeUnoptimized=3322),
|
|
ExampleSizes("pcmaudio/vumeter", cx16SizeOptimized=3862, cx16SizeUnoptimized=6221),
|
|
ExampleSizes("sprites/dragon", cx16SizeOptimized=1785, cx16SizeUnoptimized=5754),
|
|
ExampleSizes("sprites/dragons", cx16SizeOptimized=1503, cx16SizeUnoptimized=5373),
|
|
ExampleSizes("zsmkit_v1/demo1", cx16SizeOptimized=7472, cx16SizeUnoptimized=7910),
|
|
ExampleSizes("zsmkit_v1/demo2", cx16SizeOptimized=708, cx16SizeUnoptimized=2516),
|
|
// zsmkit_v1/zsmkit_high and zsmkit_v1/zsmkit_low don't compile (empty source files)
|
|
ExampleSizes("zsmkit_v2/demo", cx16SizeOptimized=790, cx16SizeUnoptimized=2868),
|
|
// zsmkit_v2/zsmkit doesn't compile (empty source file)
|
|
ExampleSizes("banking/program", cx16SizeOptimized=665, cx16SizeUnoptimized=2510),
|
|
ExampleSizes("dynamicbanking/program", cx16SizeOptimized=1211, cx16SizeUnoptimized=3089),
|
|
ExampleSizes("fileselector/standalone", cx16SizeOptimized=4135, cx16SizeUnoptimized=6070),
|
|
ExampleSizes("fileselector/main", cx16SizeOptimized=480, cx16SizeUnoptimized=2314),
|
|
// fileselector/fselector and fileselector/namesorting don't compile (empty source files)
|
|
ExampleSizes("pointers/fountain-cx16", cx16SizeOptimized=1239, cx16SizeUnoptimized=3326),
|
|
ExampleSizes("amiga", cx16SizeOptimized=7603, cx16SizeUnoptimized=11610),
|
|
ExampleSizes("audioroutines", cx16SizeOptimized=948, cx16SizeUnoptimized=1244),
|
|
ExampleSizes("automatons", cx16SizeOptimized=1037, cx16SizeUnoptimized=3094),
|
|
ExampleSizes("balloonflight", cx16SizeOptimized=3178, cx16SizeUnoptimized=5958),
|
|
ExampleSizes("bdmusic", cx16SizeOptimized=2339, cx16SizeUnoptimized=2704),
|
|
ExampleSizes("bobs", cx16SizeOptimized=2976, cx16SizeUnoptimized=4846),
|
|
ExampleSizes("bubbleuniverse", cx16SizeOptimized=1367, cx16SizeUnoptimized=1883),
|
|
ExampleSizes("charfade", cx16SizeOptimized=1054, cx16SizeUnoptimized=3126),
|
|
ExampleSizes("charsets", cx16SizeOptimized=1125, cx16SizeUnoptimized=1417),
|
|
ExampleSizes("circles", cx16SizeOptimized=2679, cx16SizeUnoptimized=6581),
|
|
ExampleSizes("cobramk3-cpu", cx16SizeOptimized=7787, cx16SizeUnoptimized=11761),
|
|
ExampleSizes("cobramk3-verafx", cx16SizeOptimized=5133, cx16SizeUnoptimized=6829),
|
|
ExampleSizes("colorbars", cx16SizeOptimized=1606, cx16SizeUnoptimized=3648),
|
|
ExampleSizes("cxlogo", cx16SizeOptimized=599, cx16SizeUnoptimized=2639),
|
|
ExampleSizes("diskspeed", cx16SizeOptimized=6111, cx16SizeUnoptimized=9829),
|
|
ExampleSizes("fileseek", cx16SizeOptimized=2462, cx16SizeUnoptimized=4291),
|
|
ExampleSizes("floatparse", cx16SizeOptimized=8303, cx16SizeUnoptimized=9171),
|
|
ExampleSizes("interpolation", cx16SizeOptimized=3824, cx16SizeUnoptimized=6504),
|
|
ExampleSizes("kefrenbars", cx16SizeOptimized=2566, cx16SizeUnoptimized=6053),
|
|
ExampleSizes("keyboardhandler", cx16SizeOptimized=412, cx16SizeUnoptimized=717),
|
|
ExampleSizes("landscape", cx16SizeOptimized=1634, cx16SizeUnoptimized=3741),
|
|
ExampleSizes("life", cx16SizeOptimized=1320, cx16SizeUnoptimized=3407),
|
|
ExampleSizes("mandelbrot", cx16SizeOptimized=1120, cx16SizeUnoptimized=1434),
|
|
ExampleSizes("multi-irq-new", cx16SizeOptimized=1073, cx16SizeUnoptimized=1519),
|
|
ExampleSizes("multi-irq-old", cx16SizeOptimized=962, cx16SizeUnoptimized=1410),
|
|
ExampleSizes("plasma", cx16SizeOptimized=1579, cx16SizeUnoptimized=3424),
|
|
ExampleSizes("rasterbars", cx16SizeOptimized=1200, cx16SizeUnoptimized=3126),
|
|
ExampleSizes("serialdownload", cx16SizeOptimized=2887, cx16SizeUnoptimized=4034),
|
|
ExampleSizes("showbmx", cx16SizeOptimized=2756, cx16SizeUnoptimized=5106),
|
|
ExampleSizes("snow", cx16SizeOptimized=3099, cx16SizeUnoptimized=6998),
|
|
ExampleSizes("sortingbench", cx16SizeOptimized=2928, cx16SizeUnoptimized=5601),
|
|
ExampleSizes("spotlight", cx16SizeOptimized=908, cx16SizeUnoptimized=3116),
|
|
ExampleSizes("starszoom", cx16SizeOptimized=2498, cx16SizeUnoptimized=6061),
|
|
ExampleSizes("test_gfx_hires", cx16SizeOptimized=4999, cx16SizeUnoptimized=8875),
|
|
ExampleSizes("test_gfx_lores", cx16SizeOptimized=6077, cx16SizeUnoptimized=8552),
|
|
ExampleSizes("testmonogfx", cx16SizeOptimized=10330, cx16SizeUnoptimized=12805),
|
|
ExampleSizes("textspotlight", cx16SizeOptimized=3431, cx16SizeUnoptimized=3788),
|
|
),
|
|
listOf(false, true)
|
|
)
|
|
|
|
val target = Cx16Target()
|
|
onlyCx16.forEach { (params, optimize) ->
|
|
val prep = prepareTestFiles(params.name, optimize, target)
|
|
test(prep.first) {
|
|
val testOutputDir = tempdir().toPath()
|
|
val filepath = prep.second
|
|
val expectedSize = if (optimize) params.cx16SizeOptimized else params.cx16SizeUnoptimized
|
|
val result = compileTheThing(filepath, optimize, target, testOutputDir)
|
|
result shouldNotBe null
|
|
if (expectedSize > 0) {
|
|
verifyOutputFileSize(result!!, expectedSize)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
class TestCompilerOnExamplesBothC64andCx16: FunSpec({
|
|
|
|
this.blockingTest = true
|
|
this.testExecutionMode = TestExecutionMode.LimitedConcurrency(kotlin.math.max(1, Runtime.getRuntime().availableProcessors()/2))
|
|
|
|
val bothCx16AndC64 = cartesianProduct(
|
|
listOf(
|
|
ExampleSizes("balls", c64SizeOptimized=885, c64SizeUnoptimized=2671, cx16SizeOptimized=874, cx16SizeUnoptimized=2948),
|
|
ExampleSizes("boingball", c64SizeOptimized=1487, c64SizeUnoptimized=1553, cx16SizeOptimized=1463, cx16SizeUnoptimized=1944),
|
|
ExampleSizes("cube3d", c64SizeOptimized=2538, c64SizeUnoptimized=3820, cx16SizeOptimized=2477, cx16SizeUnoptimized=4031),
|
|
ExampleSizes("cube3d-float", c64SizeOptimized=2390, c64SizeUnoptimized=2441, cx16SizeOptimized=2283, cx16SizeUnoptimized=2606),
|
|
ExampleSizes("cube3d-gfx", c64SizeOptimized=3648, c64SizeUnoptimized=4978, cx16SizeOptimized=2318, cx16SizeUnoptimized=3860),
|
|
ExampleSizes("dirlist", c64SizeOptimized=1515, c64SizeUnoptimized=2291, cx16SizeOptimized=1525, cx16SizeUnoptimized=3270),
|
|
ExampleSizes("fibonacci", c64SizeOptimized=582, c64SizeUnoptimized=601, cx16SizeOptimized=634, cx16SizeUnoptimized=933),
|
|
ExampleSizes("fractal-tree", c64SizeOptimized=2778, c64SizeUnoptimized=2821, cx16SizeOptimized=1168, cx16SizeUnoptimized=1462),
|
|
ExampleSizes("maze", c64SizeOptimized=2994, c64SizeUnoptimized=4931, cx16SizeOptimized=2793, cx16SizeUnoptimized=4899),
|
|
ExampleSizes("mandelbrot", c64SizeOptimized=1173, c64SizeUnoptimized=1213, cx16SizeOptimized=1120, cx16SizeUnoptimized=1434),
|
|
ExampleSizes("mandelbrot-gfx", c64SizeOptimized=1492, c64SizeUnoptimized=1514, cx16SizeOptimized=957, cx16SizeUnoptimized=1250),
|
|
ExampleSizes("multitasking", c64SizeOptimized=1900, c64SizeUnoptimized=1955, cx16SizeOptimized=1804, cx16SizeUnoptimized=2137),
|
|
ExampleSizes("numbergame", c64SizeOptimized=1034, c64SizeUnoptimized=2792, cx16SizeOptimized=1079, cx16SizeUnoptimized=3134),
|
|
ExampleSizes("primes", c64SizeOptimized=520, c64SizeUnoptimized=541, cx16SizeOptimized=565, cx16SizeUnoptimized=870),
|
|
ExampleSizes("queens", c64SizeOptimized=1053, c64SizeUnoptimized=1085, cx16SizeOptimized=1103, cx16SizeUnoptimized=1419),
|
|
ExampleSizes("screencodes", c64SizeOptimized=639, c64SizeUnoptimized=655, cx16SizeOptimized=647, cx16SizeUnoptimized=951),
|
|
ExampleSizes("swirl", c64SizeOptimized=1010, c64SizeUnoptimized=2273, cx16SizeOptimized=1039, cx16SizeUnoptimized=2592),
|
|
ExampleSizes("swirl-float", c64SizeOptimized=664, c64SizeUnoptimized=690, cx16SizeOptimized=528, cx16SizeUnoptimized=838),
|
|
ExampleSizes("tehtriz", c64SizeOptimized=4325, c64SizeUnoptimized=6349, cx16SizeOptimized=6154, cx16SizeUnoptimized=8522),
|
|
ExampleSizes("textelite", c64SizeOptimized=11227, c64SizeUnoptimized=12146, cx16SizeOptimized=10746, cx16SizeUnoptimized=12788),
|
|
ExampleSizes("pointers/animalgame", c64SizeOptimized=1965, c64SizeUnoptimized=2521, cx16SizeOptimized=1991, cx16SizeUnoptimized=2801),
|
|
ExampleSizes("pointers/binarytree", c64SizeOptimized=2672, c64SizeUnoptimized=2735, cx16SizeOptimized=2175, cx16SizeUnoptimized=2487),
|
|
ExampleSizes("pointers/hashtable", c64SizeOptimized=3388, c64SizeUnoptimized=4217, cx16SizeOptimized=2911, cx16SizeUnoptimized=3788),
|
|
ExampleSizes("pointers/sortedlist", c64SizeOptimized=1353, c64SizeUnoptimized=3137, cx16SizeOptimized=1291, cx16SizeUnoptimized=3358),
|
|
ExampleSizes("pointers/sorting", c64SizeOptimized=1776, c64SizeUnoptimized=2523, cx16SizeOptimized=1788, cx16SizeUnoptimized=2653),
|
|
),
|
|
listOf(false, true),
|
|
listOf(C64Target(), Cx16Target())
|
|
)
|
|
|
|
bothCx16AndC64.forEach { (exampleSizes, optimize, target) ->
|
|
val prep = prepareTestFiles(exampleSizes.name, optimize, target)
|
|
test(prep.first) {
|
|
val testOutputDir = tempdir().toPath()
|
|
val filepath = prep.second
|
|
val expectedSize = when (target) {
|
|
is C64Target -> if (optimize) exampleSizes.c64SizeOptimized else exampleSizes.c64SizeUnoptimized
|
|
is Cx16Target -> if (optimize) exampleSizes.cx16SizeOptimized else exampleSizes.cx16SizeUnoptimized
|
|
else -> 0
|
|
}
|
|
val result = compileTheThing(filepath, optimize, target, testOutputDir)
|
|
result shouldNotBe null
|
|
if (expectedSize > 0) {
|
|
verifyOutputFileSize(result!!, expectedSize)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
class TestCompilerOnExamplesVirtual: FunSpec({
|
|
|
|
this.blockingTest = true
|
|
this.testExecutionMode = TestExecutionMode.LimitedConcurrency(kotlin.math.max(1, Runtime.getRuntime().availableProcessors()/2))
|
|
|
|
val onlyVirtual = cartesianProduct(
|
|
listOf(
|
|
ExampleSizes("bouncegfx", virtualInstrCountOptimized=219, virtualInstrCountUnoptimized=770, virtualRegCountOptimized=90, virtualRegCountUnoptimized=342),
|
|
ExampleSizes("bsieve", virtualInstrCountOptimized=262, virtualInstrCountUnoptimized=1890, virtualRegCountOptimized=74, virtualRegCountUnoptimized=800),
|
|
ExampleSizes("fountain", virtualInstrCountOptimized=198, virtualInstrCountUnoptimized=749, virtualRegCountOptimized=80, virtualRegCountUnoptimized=335),
|
|
ExampleSizes("pixelshader", virtualInstrCountOptimized=84, virtualInstrCountUnoptimized=210, virtualRegCountOptimized=17, virtualRegCountUnoptimized=60),
|
|
ExampleSizes("sincos", virtualInstrCountOptimized=326, virtualInstrCountUnoptimized=856, virtualRegCountOptimized=141, virtualRegCountUnoptimized=374),
|
|
ExampleSizes("pointers/animalgame", virtualInstrCountOptimized=437, virtualInstrCountUnoptimized=2066, virtualRegCountOptimized=158, virtualRegCountUnoptimized=882),
|
|
ExampleSizes("pointers/binarytree", virtualInstrCountOptimized=655, virtualInstrCountUnoptimized=2233, virtualRegCountOptimized=264, virtualRegCountUnoptimized=968),
|
|
ExampleSizes("pointers/hashtable", virtualInstrCountOptimized=677, virtualInstrCountUnoptimized=2231, virtualRegCountOptimized=290, virtualRegCountUnoptimized=987),
|
|
ExampleSizes("pointers/sortedlist", virtualInstrCountOptimized=400, virtualInstrCountUnoptimized=2412, virtualRegCountOptimized=133, virtualRegCountUnoptimized=1047),
|
|
ExampleSizes("pointers/fountain-virtual", virtualInstrCountOptimized=216, virtualInstrCountUnoptimized=768, virtualRegCountOptimized=88, virtualRegCountUnoptimized=336),
|
|
ExampleSizes("pointers/sorting", virtualInstrCountOptimized=479, virtualInstrCountUnoptimized=2181, virtualRegCountOptimized=159, virtualRegCountUnoptimized=931)
|
|
),
|
|
listOf(false, true)
|
|
)
|
|
|
|
val target = VMTarget()
|
|
onlyVirtual.forEach { (params, optimize) ->
|
|
val prep = prepareTestFiles(params.name, optimize, target)
|
|
test(prep.first) {
|
|
val testOutputDir = tempdir().toPath()
|
|
val filepath = prep.second
|
|
val expectedInstrCount = if (optimize) params.virtualInstrCountOptimized else params.virtualInstrCountUnoptimized
|
|
val expectedRegCount = if (optimize) params.virtualRegCountOptimized else params.virtualRegCountUnoptimized
|
|
val result = compileTheThing(filepath, optimize, target, testOutputDir)
|
|
result shouldNotBe null
|
|
if (expectedInstrCount > 0) {
|
|
verifyIrInstructionCount(result!!, expectedInstrCount)
|
|
verifyIrRegisterCount(result, expectedRegCount)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
class TestCompilerOnExamplesPET32: FunSpec({
|
|
|
|
this.blockingTest = true
|
|
this.testExecutionMode = TestExecutionMode.LimitedConcurrency(kotlin.math.max(1, Runtime.getRuntime().availableProcessors()/2))
|
|
|
|
val onlyPET32 = cartesianProduct(
|
|
listOf(
|
|
ExampleSizes("boingball", pet32SizeOptimized=1490, pet32SizeUnoptimized=1546),
|
|
ExampleSizes("petswirl", pet32SizeOptimized=1077, pet32SizeUnoptimized=2391),
|
|
ExampleSizes("music", pet32SizeOptimized=876, pet32SizeUnoptimized=925),
|
|
),
|
|
listOf(false, true)
|
|
)
|
|
|
|
val target = PETTarget()
|
|
onlyPET32.forEach { (params, optimize) ->
|
|
val prep = prepareTestFiles(params.name, optimize, target)
|
|
test(prep.first) {
|
|
val testOutputDir = tempdir().toPath()
|
|
val filepath = prep.second
|
|
val expectedSize = if (optimize) params.pet32SizeOptimized else params.pet32SizeUnoptimized
|
|
val result = compileTheThing(filepath, optimize, target, testOutputDir)
|
|
result shouldNotBe null
|
|
if (expectedSize > 0) {
|
|
verifyOutputFileSize(result!!, expectedSize)
|
|
}
|
|
}
|
|
}
|
|
})
|