optimize silly unneeded data conversions in stackvm code

This commit is contained in:
Irmen de Jong 2018-10-05 18:31:48 +02:00
parent 6350bf8024
commit b1dcc8093a
3 changed files with 118 additions and 5 deletions

View File

@ -84,11 +84,11 @@
byte e_to
sub toscreenx(x: float, z: float) -> word {
return floor(x/(4.2+z) * height) + width // 2
return floor(x/(4.2+z) * flt(height)) + width // 2
}
sub toscreeny(y: float, z: float) -> word {
return floor(y/(4.2+z) * height) + height // 2
return floor(y/(4.2+z) * flt(height)) + height // 2
}
; draw all edges of the object

View File

@ -135,7 +135,120 @@ class StackVmProgram(val name: String, val heap: HeapValues) {
println("\nOptimizing stackVM code...")
this.instructions.removeIf { it.opcode==Opcode.NOP && it !is LabelInstr } // remove nops (that are not a label)
// todo optimize stackvm code
// - push value followed by a data type conversion -> push the value in the correct type and remove the conversion
// - push somthing followed by a discard -> remove both
val typeConversionOpcodes = setOf(
Opcode.LSB,
Opcode.MSB,
Opcode.B2WORD,
Opcode.MSB2WORD,
Opcode.B2FLOAT,
Opcode.W2FLOAT,
Opcode.DISCARD,
Opcode.DISCARD_W,
Opcode.DISCARD_F
)
val instructionsToReplace = mutableMapOf<Int, Instruction>()
val instructionsToRemove = mutableListOf<Int>()
this.instructions.withIndex().windowed(2).forEach {
if(it[1].value.opcode in typeConversionOpcodes) {
when(it[0].value.opcode) {
Opcode.PUSH -> when (it[1].value.opcode) {
Opcode.LSB -> instructionsToRemove.add(it[1].index)
Opcode.MSB -> throw CompilerException("msb of a byte")
Opcode.B2WORD -> {
val ins = Instruction(Opcode.PUSH_W, Value(DataType.WORD, it[0].value.arg!!.integerValue()))
instructionsToReplace[it[0].index] = ins
instructionsToRemove.add(it[1].index)
}
Opcode.MSB2WORD -> {
val ins = Instruction(Opcode.PUSH_W, Value(DataType.WORD, 256 * it[0].value.arg!!.integerValue()))
instructionsToReplace[it[0].index] = ins
instructionsToRemove.add(it[1].index)
}
Opcode.B2FLOAT -> {
val ins = Instruction(Opcode.PUSH_F, Value(DataType.FLOAT, it[0].value.arg!!.integerValue().toDouble()))
instructionsToReplace[it[0].index] = ins
instructionsToRemove.add(it[1].index)
}
Opcode.W2FLOAT -> throw CompilerException("invalid conversion following a byte")
Opcode.DISCARD -> {
instructionsToRemove.add(it[0].index)
instructionsToRemove.add(it[1].index)
}
Opcode.DISCARD_W, Opcode.DISCARD_F -> throw CompilerException("invalid discard type following a byte")
else -> {}
}
Opcode.PUSH_W -> when (it[1].value.opcode) {
Opcode.LSB -> {
val ins = Instruction(Opcode.PUSH, Value(DataType.BYTE, it[0].value.arg!!.integerValue() and 255))
instructionsToReplace[it[0].index] = ins
instructionsToRemove.add(it[1].index)
}
Opcode.MSB -> {
val ins = Instruction(Opcode.PUSH, Value(DataType.BYTE, it[0].value.arg!!.integerValue() ushr 8 and 255))
instructionsToReplace[it[0].index] = ins
instructionsToRemove.add(it[1].index)
}
Opcode.B2WORD,
Opcode.MSB2WORD,
Opcode.B2FLOAT -> throw CompilerException("invalid conversion following a word")
Opcode.W2FLOAT -> {
val ins = Instruction(Opcode.PUSH_F, Value(DataType.FLOAT, it[0].value.arg!!.integerValue().toDouble()))
instructionsToReplace[it[0].index] = ins
instructionsToRemove.add(it[1].index)
}
Opcode.DISCARD_W -> {
instructionsToRemove.add(it[0].index)
instructionsToRemove.add(it[1].index)
}
Opcode.DISCARD, Opcode.DISCARD_F -> throw CompilerException("invalid discard type following a byte")
else -> {}
}
Opcode.PUSH_F -> when (it[1].value.opcode) {
Opcode.LSB,
Opcode.MSB,
Opcode.B2WORD,
Opcode.MSB2WORD,
Opcode.B2FLOAT,
Opcode.W2FLOAT -> throw CompilerException("invalid conversion following a float")
Opcode.DISCARD_F -> {
instructionsToRemove.add(it[0].index)
instructionsToRemove.add(it[1].index)
}
Opcode.DISCARD, Opcode.DISCARD_W -> throw CompilerException("invalid discard type following a float")
else -> {}
}
Opcode.PUSH_VAR_F,
Opcode.PUSH_VAR_W,
Opcode.PUSH_VAR,
Opcode.PUSH_MEM,
Opcode.PUSH_MEM_W,
Opcode.PUSH_MEM_F -> when (it[1].value.opcode) {
Opcode.DISCARD_F, Opcode.DISCARD_W, Opcode.DISCARD -> {
instructionsToRemove.add(it[0].index)
instructionsToRemove.add(it[1].index)
}
else -> {}
}
else -> {}
}
}
}
for(rins in instructionsToReplace) {
instructions[rins.key] = rins.value
}
for(ins in instructionsToRemove.reversed()) {
instructions.removeAt(ins)
}
// todo optimize stackvm code more
}
fun blockvar(scopedname: String, decl: VarDecl) {

View File

@ -103,10 +103,10 @@ enum class Opcode {
BITXOR_W,
INV,
INV_W,
// numeric type conversions
LSB,
MSB,
// numeric type conversions not covered by other opcodes
B2WORD, // convert a byte into a word where it is the lower eight bits $00xx
MSB2WORD, // convert a byte into a word where it is the upper eight bits $xx00
B2FLOAT, // convert byte into floating point