more Rpn optimizations

This commit is contained in:
Irmen de Jong
2023-03-19 00:24:05 +01:00
parent 52b560e72d
commit 6e4ae034b2
14 changed files with 551 additions and 164 deletions
@@ -898,6 +898,7 @@ class IRCodeGen(
private fun translate(ifElse: PtIfElse): IRCodeChunks {
val condition = ifElse.condition
val goto = ifElse.ifScope.children.firstOrNull() as? PtJump
when (condition) {
is PtBinaryExpression -> {
if(condition.operator !in ComparisonOperators)
@@ -905,7 +906,6 @@ class IRCodeGen(
val signed = condition.left.type in SignedDatatypes
val irDtLeft = irType(condition.left.type)
val goto = ifElse.ifScope.children.firstOrNull() as? PtJump
return when {
goto!=null && ifElse.elseScope.children.isEmpty() -> translateIfFollowedByJustGoto(ifElse, goto, irDtLeft, signed)
constValue(condition.right) == 0.0 -> translateIfElseZeroComparison(ifElse, irDtLeft, signed)
@@ -913,52 +913,92 @@ class IRCodeGen(
}
}
is PtRpn -> {
TODO("RPN ifelse (intermediate codegen) $condition")
val (left, oper, right) = condition.finalOperation()
if(oper.operator !in ComparisonOperators)
throw AssemblyError("if condition should only be a binary comparison expression")
val signed = oper.leftType in SignedDatatypes
val irDtLeft = irType(oper.leftType)
return when {
goto!=null && ifElse.elseScope.children.isEmpty() -> translateIfFollowedByJustGotoRPN(ifElse, goto, irDtLeft, signed)
constValue(right as PtExpression) == 0.0 -> translateIfElseZeroComparisonRPN(ifElse, irDtLeft, signed)
else -> translateIfElseNonZeroComparisonRPN(ifElse, irDtLeft, signed)
}
}
else -> {
TODO("weird condition node: $condition")
throw AssemblyError("weird condition node: $condition")
}
}
}
private fun translateIfFollowedByJustGotoRPN(ifElse: PtIfElse, goto: PtJump, irDtLeft: IRDataType, signed: Boolean): MutableList<IRCodeChunkBase> {
TODO("RPN translateIfFollowedByJustGotoRPN")
}
private fun translateIfElseZeroComparisonRPN(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {
TODO("RPN translateIfElseZeroComparisonRPN")
}
private fun translateIfElseNonZeroComparisonRPN(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {
TODO("RPN translateIfElseNonZeroComparisonRPN")
}
private fun translateIfFollowedByJustGoto(ifElse: PtIfElse, goto: PtJump, irDtLeft: IRDataType, signed: Boolean): MutableList<IRCodeChunkBase> {
if(program.binaryExpressionsAreRPN) {
TODO ("RPN (intermediate codegen)")
require(!program.binaryExpressionsAreRPN)
val condition = ifElse.condition as PtBinaryExpression
val result = mutableListOf<IRCodeChunkBase>()
if (irDtLeft == IRDataType.FLOAT) {
val leftTr = expressionEval.translateExpression(condition.left)
addToResult(result, leftTr, -1, leftTr.resultFpReg)
val rightTr = expressionEval.translateExpression(condition.right)
addToResult(result, rightTr, -1, rightTr.resultFpReg)
result += IRCodeChunk(null, null).also {
val compResultReg = registers.nextFree()
it += IRInstruction(
Opcode.FCOMP,
IRDataType.FLOAT,
reg1 = compResultReg,
fpReg1 = leftTr.resultFpReg,
fpReg2 = rightTr.resultFpReg
)
val gotoOpcode = when (condition.operator) {
"==" -> Opcode.BZ
"!=" -> Opcode.BNZ
"<" -> Opcode.BLEZS
">" -> Opcode.BGEZS
"<=" -> Opcode.BLZS
">=" -> Opcode.BGZS
else -> throw AssemblyError("weird operator")
}
it += if (goto.address != null)
IRInstruction(
gotoOpcode,
IRDataType.BYTE,
reg1 = compResultReg,
value = goto.address?.toInt()
)
else if (goto.generatedLabel != null)
IRInstruction(
gotoOpcode,
IRDataType.BYTE,
reg1 = compResultReg,
labelSymbol = goto.generatedLabel
)
else
IRInstruction(
gotoOpcode,
IRDataType.BYTE,
reg1 = compResultReg,
labelSymbol = goto.identifier!!.name
)
}
return result
} else {
val result = mutableListOf<IRCodeChunkBase>()
val condition = ifElse.condition as PtBinaryExpression
if(irDtLeft==IRDataType.FLOAT) {
val leftTr = expressionEval.translateExpression(condition.left)
addToResult(result, leftTr, -1, leftTr.resultFpReg)
val rightTr = expressionEval.translateExpression(condition.right)
addToResult(result, rightTr, -1, rightTr.resultFpReg)
result += IRCodeChunk(null,null).also {
val compResultReg = registers.nextFree()
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg)
val gotoOpcode = when (condition.operator) {
"==" -> Opcode.BZ
"!=" -> Opcode.BNZ
"<" -> Opcode.BLEZS
">" -> Opcode.BGEZS
"<=" -> Opcode.BLZS
">=" -> Opcode.BGZS
else -> throw AssemblyError("weird operator")
}
it += if (goto.address != null)
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, value = goto.address?.toInt())
else if (goto.generatedLabel != null)
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, labelSymbol = goto.generatedLabel)
else
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, labelSymbol = goto.identifier!!.name)
}
return result
} else {
val rightConst = condition.right.asConstInteger()
return if(rightConst==0)
ifZeroIntThenJump(result, ifElse, signed, irDtLeft, goto)
else {
ifNonZeroIntThenJump(result, ifElse, signed, irDtLeft, goto)
}
val rightConst = condition.right.asConstInteger()
return if (rightConst == 0)
ifZeroIntThenJump(result, ifElse, signed, irDtLeft, goto)
else {
ifNonZeroIntThenJump(result, ifElse, signed, irDtLeft, goto)
}
}
}