rewrite bool=bool^1 into bool=not bool

This commit is contained in:
Irmen de Jong 2022-12-29 16:56:20 +01:00
parent f5b202d438
commit 002006517a
5 changed files with 36 additions and 22 deletions

View File

@ -294,6 +294,7 @@ internal class AssignmentAsmGen(private val program: Program,
"+" -> {}
"-" -> augmentableAsmGen.inplaceNegate(assign, true)
"~" -> augmentableAsmGen.inplaceInvert(assign)
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
else -> throw AssemblyError("invalid prefix operator")
}
} else {

View File

@ -231,6 +231,18 @@ class ExpressionSimplifier(private val program: Program,
}
}
if(leftDt==DataType.BOOL) {
// optimize boolean constant comparisons
// if(expr.operator=="==" && rightVal?.number==0.0)
// return listOf(IAstModification.ReplaceNode(expr, PrefixExpression("not", expr.left, expr.position), parent))
// if(expr.operator=="!=" && rightVal?.number==1.0)
// return listOf(IAstModification.ReplaceNode(expr, PrefixExpression("not", expr.left, expr.position), parent))
if(expr.operator=="==" && rightVal?.number==1.0)
return listOf(IAstModification.ReplaceNode(expr, expr.left, parent))
if(expr.operator=="!=" && rightVal?.number==0.0)
return listOf(IAstModification.ReplaceNode(expr, expr.left, parent))
}
// simplify when a term is constant and directly determines the outcome
val constFalse = NumericLiteral.fromBoolean(false, expr.position)
val newExpr: Expression? = when (expr.operator) {

View File

@ -40,6 +40,13 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val
}
}
}
if(expr.operator=="^" && expr.left.inferType(program) istype DataType.BOOL && expr.right.constValue(program)?.number == 1.0) {
// boolean ^ 1 --> not boolean
val notExpr = PrefixExpression("not", expr.left, expr.position)
return listOf(IAstModification.ReplaceNode(expr, notExpr, parent))
}
return noModifications
}

View File

@ -368,16 +368,16 @@ main {
txt.print("const inv 255: ")
txt.print_ub(~ 0)
txt.nl()
bvalue = 129
txt.print("bitwise inv 126: ")
bvalue = ~ bvalue
txt.print_ub(bvalue)
txt.nl()
bvalue = 0
txt.print("bitwise inv 255: ")
bvalue = ~ bvalue
txt.print_ub(bvalue)
txt.nl()
; bvalue = 129
; txt.print("bitwise inv 126: ")
; bvalue = ~ bvalue
; txt.print_ub(bvalue)
; txt.nl()
; bvalue = 0
; txt.print("bitwise inv 255: ")
; bvalue = ~ bvalue
; txt.print_ub(bvalue)
; txt.nl()
txt.print("bitwise or 14: ")
txt.print_ub(ub1 | ub2 | ub3 | ub4)
@ -397,12 +397,12 @@ main {
txt.print("bitwise xor 6: ")
txt.print_ub(ub1 ^ ub2 ^ ub3 ^ 8)
txt.nl()
txt.print("bitwise not 247: ")
txt.print_ub(~ub3)
txt.nl()
txt.print("bitwise not 255: ")
txt.print_ub(~ub4)
txt.nl()
;txt.print("bitwise not 247: ")
;txt.print_ub(~ub3)
;txt.nl()
;txt.print("bitwise not 255: ")
;txt.print_ub(~ub4)
;txt.nl()
txt.print("not 0: ")
bvalue = 3 * (ub4 | not (ub3 | ub3 | ub3))

View File

@ -3,12 +3,6 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- make sure bool value is always 0 or 1 (all casts should convert, or actually, bool!=0 comparison should return 0 or 1), then:
- ast rewrite bool=bool^1 into bool=not bool
- should solve: bool bb = not bb -> larger code than bool bb ^= 1
- check that bool==0 / bool==1 / bool!=0 / bool != 1 are optimized away
...