mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
removing redundant compares
This commit is contained in:
parent
09d506194f
commit
ff8de8e42d
@ -17,6 +17,8 @@ internal class ExpressionCodeResult(val chunks: IRCodeChunks, val dt: IRDataType
|
|||||||
if(resultReg!=-1) require(resultFpReg==-1)
|
if(resultReg!=-1) require(resultFpReg==-1)
|
||||||
if(resultFpReg!=-1) require(resultReg==-1)
|
if(resultFpReg!=-1) require(resultReg==-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun lastInstruction() = chunks.last().instructions.last()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||||
|
@ -470,7 +470,6 @@ class IRCodeGen(
|
|||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = 0), null)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = 0), null)
|
||||||
result += IRCodeChunk(loopLabel, null).also {
|
result += IRCodeChunk(loopLabel, null).also {
|
||||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1 = tmpReg, reg2 = indexReg, labelSymbol = iterable.name)
|
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1 = tmpReg, reg2 = indexReg, labelSymbol = iterable.name)
|
||||||
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1 = tmpReg, immediate = 0)
|
|
||||||
it += IRInstruction(Opcode.BSTEQ, labelSymbol = endLabel)
|
it += IRInstruction(Opcode.BSTEQ, labelSymbol = endLabel)
|
||||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tmpReg, labelSymbol = loopvarSymbol)
|
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tmpReg, labelSymbol = loopvarSymbol)
|
||||||
}
|
}
|
||||||
@ -499,7 +498,10 @@ class IRCodeGen(
|
|||||||
result += translateNode(forLoop.statements)
|
result += translateNode(forLoop.statements)
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=indexReg)
|
it += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=indexReg)
|
||||||
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=indexReg, immediate = if(iterableLength==256) 0 else iterableLength)
|
if(iterableLength!=256) {
|
||||||
|
// for length 256, the compare is actually against 0, which doesn't require a separate CMP instruction
|
||||||
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=indexReg, immediate = iterableLength)
|
||||||
|
}
|
||||||
it += IRInstruction(Opcode.BSTNE, labelSymbol = loopLabel)
|
it += IRInstruction(Opcode.BSTNE, labelSymbol = loopLabel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -516,7 +518,10 @@ class IRCodeGen(
|
|||||||
result += translateNode(forLoop.statements)
|
result += translateNode(forLoop.statements)
|
||||||
result += addConstReg(IRDataType.BYTE, indexReg, elementSize)
|
result += addConstReg(IRDataType.BYTE, indexReg, elementSize)
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=indexReg, immediate = if(lengthBytes==256) 0 else lengthBytes)
|
if(lengthBytes!=256) {
|
||||||
|
// for length 256, the compare is actually against 0, which doesn't require a separate CMP instruction
|
||||||
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=indexReg, immediate = lengthBytes)
|
||||||
|
}
|
||||||
it += IRInstruction(Opcode.BSTNE, labelSymbol = loopLabel)
|
it += IRInstruction(Opcode.BSTNE, labelSymbol = loopLabel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -976,7 +981,6 @@ class IRCodeGen(
|
|||||||
fpReg2 = rightTr.resultFpReg
|
fpReg2 = rightTr.resultFpReg
|
||||||
)
|
)
|
||||||
when(condition.operator) {
|
when(condition.operator) {
|
||||||
// TODO: the converted list of operators
|
|
||||||
"==" -> {
|
"==" -> {
|
||||||
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1 = compResultReg, immediate = 0)
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1 = compResultReg, immediate = 0)
|
||||||
it += branchInstr(goto, Opcode.BSTEQ)
|
it += branchInstr(goto, Opcode.BSTEQ)
|
||||||
@ -986,7 +990,6 @@ class IRCodeGen(
|
|||||||
it += branchInstr(goto, Opcode.BSTNE)
|
it += branchInstr(goto, Opcode.BSTNE)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// TODO: the old list of operators, still to be converted
|
|
||||||
val gotoOpcode = when (condition.operator) {
|
val gotoOpcode = when (condition.operator) {
|
||||||
"<" -> Opcode.BLTS
|
"<" -> Opcode.BLTS
|
||||||
">" -> Opcode.BGTS
|
">" -> Opcode.BGTS
|
||||||
@ -1016,7 +1019,7 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use this everywhere
|
// TODO use this everywhere a PtJump is used
|
||||||
private fun branchInstr(goto: PtJump, branchOpcode: Opcode) = if (goto.address != null)
|
private fun branchInstr(goto: PtJump, branchOpcode: Opcode) = if (goto.address != null)
|
||||||
IRInstruction(branchOpcode, address = goto.address?.toInt())
|
IRInstruction(branchOpcode, address = goto.address?.toInt())
|
||||||
else if (goto.generatedLabel != null)
|
else if (goto.generatedLabel != null)
|
||||||
@ -1034,18 +1037,19 @@ class IRCodeGen(
|
|||||||
val condition = ifElse.condition as PtBinaryExpression
|
val condition = ifElse.condition as PtBinaryExpression
|
||||||
val leftTr = expressionEval.translateExpression(condition.left)
|
val leftTr = expressionEval.translateExpression(condition.left)
|
||||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||||
|
val requireCompareZero = leftTr.lastInstruction().opcode !in OpcodesThatSetStatusbits
|
||||||
when(condition.operator) {
|
when(condition.operator) {
|
||||||
// TODO: converted list of operators
|
|
||||||
"==" -> {
|
"==" -> {
|
||||||
|
if(requireCompareZero)
|
||||||
addInstr(result, IRInstruction(Opcode.CMPI, irDtLeft, reg1 = leftTr.resultReg, immediate = 0), null)
|
addInstr(result, IRInstruction(Opcode.CMPI, irDtLeft, reg1 = leftTr.resultReg, immediate = 0), null)
|
||||||
addInstr(result, branchInstr(goto, Opcode.BSTEQ), null)
|
addInstr(result, branchInstr(goto, Opcode.BSTEQ), null)
|
||||||
}
|
}
|
||||||
"!=" -> {
|
"!=" -> {
|
||||||
|
if(requireCompareZero)
|
||||||
addInstr(result, IRInstruction(Opcode.CMPI, irDtLeft, reg1 = leftTr.resultReg, immediate = 0), null)
|
addInstr(result, IRInstruction(Opcode.CMPI, irDtLeft, reg1 = leftTr.resultReg, immediate = 0), null)
|
||||||
addInstr(result, branchInstr(goto, Opcode.BSTNE), null)
|
addInstr(result, branchInstr(goto, Opcode.BSTNE), null)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// TODO: to-be converted operators
|
|
||||||
val opcode = when (condition.operator) {
|
val opcode = when (condition.operator) {
|
||||||
"<" -> if (signed) Opcode.BLTS else Opcode.BLT
|
"<" -> if (signed) Opcode.BLTS else Opcode.BLT
|
||||||
">" -> if (signed) Opcode.BGTS else Opcode.BGT
|
">" -> if (signed) Opcode.BGTS else Opcode.BGT
|
||||||
@ -1072,12 +1076,13 @@ class IRCodeGen(
|
|||||||
) {
|
) {
|
||||||
val condition = ifElse.condition as? PtBinaryExpression
|
val condition = ifElse.condition as? PtBinaryExpression
|
||||||
if(condition==null) {
|
if(condition==null) {
|
||||||
val tr = expressionEval.translateExpression(ifElse.condition)
|
throw AssemblyError("expected condition")
|
||||||
result += tr.chunks
|
// val tr = expressionEval.translateExpression(ifElse.condition)
|
||||||
result += IRCodeChunk(null, null).also {
|
// result += tr.chunks
|
||||||
it += IRInstruction(Opcode.CMPI, irDtLeft, reg1 = tr.resultReg, immediate = 0)
|
// result += IRCodeChunk(null, null).also {
|
||||||
it += branchInstr(goto, Opcode.BSTNE)
|
// it += IRInstruction(Opcode.CMPI, irDtLeft, reg1 = tr.resultReg, immediate = 0) // was redundant CMP most likely
|
||||||
}
|
// it += branchInstr(goto, Opcode.BSTNE)
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
val leftTr = expressionEval.translateExpression(condition.left)
|
val leftTr = expressionEval.translateExpression(condition.left)
|
||||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||||
@ -1085,7 +1090,6 @@ class IRCodeGen(
|
|||||||
if(number!=null) {
|
if(number!=null) {
|
||||||
val firstReg = leftTr.resultReg
|
val firstReg = leftTr.resultReg
|
||||||
when(condition.operator) {
|
when(condition.operator) {
|
||||||
// TODO: the converted operators
|
|
||||||
"==" -> {
|
"==" -> {
|
||||||
addInstr(result, IRInstruction(Opcode.CMPI, irDtLeft, reg1 = firstReg, immediate = number), null)
|
addInstr(result, IRInstruction(Opcode.CMPI, irDtLeft, reg1 = firstReg, immediate = number), null)
|
||||||
addInstr(result, branchInstr(goto, Opcode.BSTEQ), null)
|
addInstr(result, branchInstr(goto, Opcode.BSTEQ), null)
|
||||||
@ -1095,7 +1099,6 @@ class IRCodeGen(
|
|||||||
addInstr(result, branchInstr(goto, Opcode.BSTNE), null)
|
addInstr(result, branchInstr(goto, Opcode.BSTNE), null)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// TODO: to-be converted operators
|
|
||||||
val opcode = when (condition.operator) {
|
val opcode = when (condition.operator) {
|
||||||
"<" -> if(signed) Opcode.BLTS else Opcode.BLT
|
"<" -> if(signed) Opcode.BLTS else Opcode.BLT
|
||||||
">" -> if(signed) Opcode.BGTS else Opcode.BGT
|
">" -> if(signed) Opcode.BGTS else Opcode.BGT
|
||||||
@ -1267,33 +1270,6 @@ class IRCodeGen(
|
|||||||
val condition = ifElse.condition as? PtBinaryExpression
|
val condition = ifElse.condition as? PtBinaryExpression
|
||||||
if(condition==null) {
|
if(condition==null) {
|
||||||
throw AssemblyError("if-else condition is not a binaryexpression, should have been converted?")
|
throw AssemblyError("if-else condition is not a binaryexpression, should have been converted?")
|
||||||
// if(irDtLeft==IRDataType.FLOAT)
|
|
||||||
// throw AssemblyError("condition value should not be float")
|
|
||||||
// val tr = expressionEval.translateExpression(ifElse.condition)
|
|
||||||
// result += tr.chunks
|
|
||||||
// if(ifElse.elseScope.children.isNotEmpty()) {
|
|
||||||
// val elseLabel = createLabelName()
|
|
||||||
// result += IRCodeChunk(null, null).also {
|
|
||||||
// it += IRInstruction(Opcode.CMPI, irDtLeft, reg1=tr.resultReg, immediate = 0)
|
|
||||||
// it += IRInstruction(Opcode.BSTEQ, labelSymbol = elseLabel)
|
|
||||||
// TODO("test this")
|
|
||||||
// }
|
|
||||||
// result += translateNode(ifElse.ifScope)
|
|
||||||
// val afterIfLabel = createLabelName()
|
|
||||||
// addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null)
|
|
||||||
// result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
|
|
||||||
// result += IRCodeChunk(afterIfLabel, null)
|
|
||||||
// } else {
|
|
||||||
// val afterIfLabel = createLabelName()
|
|
||||||
// result += IRCodeChunk(null, null).also {
|
|
||||||
// it += IRInstruction(Opcode.CMPI, irDtLeft, reg1=tr.resultReg, immediate = 0)
|
|
||||||
// it += IRInstruction(Opcode.BSTEQ, labelSymbol = afterIfLabel)
|
|
||||||
// TODO("test this")
|
|
||||||
// }
|
|
||||||
// result += translateNode(ifElse.ifScope)
|
|
||||||
// result += IRCodeChunk(afterIfLabel, null)
|
|
||||||
// }
|
|
||||||
// return result
|
|
||||||
} else {
|
} else {
|
||||||
if (irDtLeft == IRDataType.FLOAT) {
|
if (irDtLeft == IRDataType.FLOAT) {
|
||||||
val leftTr = expressionEval.translateExpression(condition.left)
|
val leftTr = expressionEval.translateExpression(condition.left)
|
||||||
@ -1641,10 +1617,7 @@ class IRCodeGen(
|
|||||||
addToResult(result, countTr, countTr.resultReg, -1)
|
addToResult(result, countTr, countTr.resultReg, -1)
|
||||||
if(constIntValue(repeat.count)==null) {
|
if(constIntValue(repeat.count)==null) {
|
||||||
// check if the counter is already zero
|
// check if the counter is already zero
|
||||||
result += IRCodeChunk(null, null).also {
|
addInstr(result, IRInstruction(Opcode.BSTEQ, labelSymbol = skipRepeatLabel), null)
|
||||||
it += IRInstruction(Opcode.CMPI, irDt, reg1=countTr.resultReg, immediate = 0)
|
|
||||||
it += IRInstruction(Opcode.BSTEQ, labelSymbol = skipRepeatLabel)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? Bitwise operations, etc), but only after setting the status bits is verified!
|
- IR: use branchInstr() everywhere a PtGoto is used in IRCodeGen
|
||||||
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%import textio
|
%import textio
|
||||||
|
|
||||||
txt {
|
main {
|
||||||
%option merge
|
sub start() {
|
||||||
sub println(uword string) {
|
ubyte xx=12
|
||||||
txt.print(string)
|
|
||||||
|
if xx==12
|
||||||
|
txt.print("gottem")
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
sub start() {
|
|
||||||
txt.lowercase()
|
|
||||||
txt.println("Hello, world1")
|
|
||||||
txt.println("Hello, world2")
|
|
||||||
txt.println("Hello, world3")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -437,6 +437,7 @@ val OpcodesThatSetStatusbitsButNotCarry = setOf(
|
|||||||
Opcode.DEC,
|
Opcode.DEC,
|
||||||
Opcode.DECM
|
Opcode.DECM
|
||||||
)
|
)
|
||||||
|
val OpcodesThatSetStatusbits = OpcodesThatSetStatusbitsButNotCarry + OpcodesThatSetStatusbitsIncludingCarry
|
||||||
|
|
||||||
|
|
||||||
enum class IRDataType {
|
enum class IRDataType {
|
||||||
|
Loading…
Reference in New Issue
Block a user