IR: optimized when statement translation

This commit is contained in:
Irmen de Jong 2023-07-16 12:10:46 +02:00
parent b3cb9b7fe2
commit c1aa5d4e47
2 changed files with 38 additions and 31 deletions

View File

@ -399,42 +399,35 @@ class IRCodeGen(
} }
private fun translate(whenStmt: PtWhen): IRCodeChunks { private fun translate(whenStmt: PtWhen): IRCodeChunks {
if(whenStmt.choices.children.isEmpty())
return emptyList()
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
val valueDt = irType(whenStmt.value.type) val valueDt = irType(whenStmt.value.type)
val valueTr = expressionEval.translateExpression(whenStmt.value) val valueTr = expressionEval.translateExpression(whenStmt.value)
addToResult(result, valueTr, valueTr.resultReg, -1) addToResult(result, valueTr, valueTr.resultReg, -1)
val choices = whenStmt.choices.children.map {it as PtWhenChoice }
val choices = mutableListOf<Pair<String, PtWhenChoice>>()
val endLabel = createLabelName() val endLabel = createLabelName()
for (choice in choices) { whenStmt.choices.children.forEach {
val choice = it as PtWhenChoice
if(choice.isElse) { if(choice.isElse) {
result += translateNode(choice.statements) result += translateNode(choice.statements)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
} else { } else {
val skipLabel = createLabelName() val choiceLabel = createLabelName()
val values = choice.values.children.map {it as PtNumber} choices.add(choiceLabel to choice)
if(values.size==1) { choice.values.children.map { it as PtNumber }.sortedBy { it.number }.forEach { value ->
val chunk = IRCodeChunk(null, null) addInstr(result, IRInstruction(Opcode.BEQ, valueDt, reg1=valueTr.resultReg, immediate = value.number.toInt(), labelSymbol = choiceLabel), null)
chunk += IRInstruction(Opcode.BNE, valueDt, reg1=valueTr.resultReg, immediate = values[0].number.toInt(), labelSymbol = skipLabel)
result += chunk
result += translateNode(choice.statements)
if(choice.statements.children.last() !is PtReturn)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
} else {
val matchLabel = createLabelName()
val chunk = IRCodeChunk(null, null)
for (value in values) {
chunk += IRInstruction(Opcode.BEQ, valueDt, reg1=valueTr.resultReg, immediate = value.number.toInt(), labelSymbol = matchLabel)
}
chunk += IRInstruction(Opcode.JUMP, labelSymbol = skipLabel)
result += chunk
result += labelFirstChunk(translateNode(choice.statements), matchLabel)
if(choice.statements.children.last() !is PtReturn)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
} }
result += IRCodeChunk(skipLabel, null)
} }
} }
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
choices.forEach { (label, choice) ->
result += labelFirstChunk(translateNode(choice.statements), label)
val lastStatement = choice.statements.children.last()
if(lastStatement !is PtReturn && lastStatement !is PtJump)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
}
result += IRCodeChunk(endLabel, null) result += IRCodeChunk(endLabel, null)
return result return result
} }

View File

@ -5,13 +5,27 @@ main
{ {
sub start() sub start()
{ {
ubyte a=1 ubyte res
ubyte b=2 ubyte val=3
ubyte c=3 when val*10 {
ubyte d=4 1 -> res=1
10 -> res=10
20 -> res=20
30 -> res=30
40 -> res=40
else -> res=0
}
ubyte xx = (a*b)+(c*d) txt.print_ub(res) ; 30
xx++ txt.nl()
when val {
5,7,9,1,3 -> res=100
2,4,6,8 -> res=200
else -> res=0
}
txt.print_ub(res) ; 100
; 102 instructions, 31 registers, 122 steps
} }
} }