mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
optimize silly unneeded data conversions in stackvm code
This commit is contained in:
parent
6350bf8024
commit
b1dcc8093a
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user