mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
apply De Morgan's laws for logical not, results in smaller code
This commit is contained in:
parent
8ba5a0d90c
commit
8a0e650511
@ -48,6 +48,34 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val
|
|||||||
return listOf(IAstModification.ReplaceNode(expr, notExpr, parent))
|
return listOf(IAstModification.ReplaceNode(expr, notExpr, parent))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// applying De Morgan's laws proved beneficial for the code generator,
|
||||||
|
// when the code has one outer 'not' instead of two inner ones.
|
||||||
|
if(expr.operator=="or" || expr.operator=="and") {
|
||||||
|
val newOper = if(expr.operator=="or") "and" else "or"
|
||||||
|
val leftP = expr.left as? PrefixExpression
|
||||||
|
val rightP = expr.right as? PrefixExpression
|
||||||
|
if(leftP!=null && leftP.operator=="not" && rightP!=null && rightP.operator=="not") {
|
||||||
|
// (not a) or (not b) --> not(a and b)
|
||||||
|
// (not a) and (not b) --> not(a or b)
|
||||||
|
val inner = BinaryExpression(leftP.expression, newOper, rightP.expression, expr.position)
|
||||||
|
val notExpr = PrefixExpression("not", inner, expr.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(expr, notExpr, parent))
|
||||||
|
}
|
||||||
|
val leftB = expr.left as? BinaryExpression
|
||||||
|
val rightB = expr.right as? BinaryExpression
|
||||||
|
if(leftB!=null && leftB.operator=="==" && (leftB.right as? NumericLiteral)?.number==0.0
|
||||||
|
&& rightB!=null && rightB.operator=="==" && (rightB.right as? NumericLiteral)?.number==0.0) {
|
||||||
|
// a==0 or b==0 --> (a!=0 and b!=0)==0
|
||||||
|
// a==0 and b==0 --> (a!=0 or b!=0)==0
|
||||||
|
leftB.operator = "!="
|
||||||
|
rightB.operator = "!="
|
||||||
|
val inner = BinaryExpression(leftB, newOper, rightB, expr.position)
|
||||||
|
val notExpr = BinaryExpression(inner, "==", NumericLiteral.optimalInteger(0, expr.position), expr.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(expr, notExpr, parent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,8 +307,8 @@ class TestOptimization: FunSpec({
|
|||||||
a1 = not a1 ; a1 = a1==0
|
a1 = not a1 ; a1 = a1==0
|
||||||
a1 = not not a1 ; a1 = a1, so removed totally
|
a1 = not not a1 ; a1 = a1, so removed totally
|
||||||
a1 = not not not a1 ; a1 = a1==0
|
a1 = not not not a1 ; a1 = a1==0
|
||||||
a1 = not a1 or not a2 ; a1 = a1==0 or a2==0
|
a1 = not a1 or not a2 ; a1 = (a1 and a2)==0
|
||||||
a1 = not a1 and not a2 ; a1 = a1==0 and a2==0
|
a1 = not a1 and not a2 ; a1 = (a1 or a2)==0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -324,8 +324,12 @@ class TestOptimization: FunSpec({
|
|||||||
value1.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
value1.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
value2.operator shouldBe "=="
|
value2.operator shouldBe "=="
|
||||||
value2.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
value2.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
value3.operator shouldBe "or"
|
value3.operator shouldBe "=="
|
||||||
value4.operator shouldBe "and"
|
value3.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
|
(value3.left as BinaryExpression).operator shouldBe "and"
|
||||||
|
value4.operator shouldBe "=="
|
||||||
|
value4.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
|
(value4.left as BinaryExpression).operator shouldBe "or"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("various 'not' operator rewrites with optimizations") {
|
test("various 'not' operator rewrites with optimizations") {
|
||||||
@ -337,8 +341,8 @@ class TestOptimization: FunSpec({
|
|||||||
a1 = not a1 ; a1 = a1==0
|
a1 = not a1 ; a1 = a1==0
|
||||||
a1 = not not a1 ; a1 = a1, so removed totally
|
a1 = not not a1 ; a1 = a1, so removed totally
|
||||||
a1 = not not not a1 ; a1 = a1==0
|
a1 = not not not a1 ; a1 = a1==0
|
||||||
a1 = not a1 or not a2 ; a1 = a1==0 or a2==0
|
a1 = not a1 or not a2 ; a1 = (a1 and a2)==0
|
||||||
a1 = not a1 and not a2 ; a1 = a1==0 and a2==0
|
a1 = not a1 and not a2 ; a1 = (a1 or a2)==0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -354,8 +358,12 @@ class TestOptimization: FunSpec({
|
|||||||
value1.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
value1.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
value2.operator shouldBe "=="
|
value2.operator shouldBe "=="
|
||||||
value2.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
value2.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
value3.operator shouldBe "or"
|
value3.operator shouldBe "=="
|
||||||
value4.operator shouldBe "and"
|
value3.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
|
(value3.left as BinaryExpression).operator shouldBe "and"
|
||||||
|
value4.operator shouldBe "=="
|
||||||
|
value4.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
|
(value4.left as BinaryExpression).operator shouldBe "or"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("asmgen correctly deals with float typecasting in augmented assignment") {
|
test("asmgen correctly deals with float typecasting in augmented assignment") {
|
||||||
|
@ -4,18 +4,31 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte @shared rnr = $a0
|
; is optimizing this useful? : not a1 or not a2 -> not(a1 and a2) likewise for and.
|
||||||
txt.print_ub(rnr>=$33)
|
bool @shared a1 = true
|
||||||
txt.print_ub(rnr>=$66)
|
bool @shared a2
|
||||||
txt.print_ub(rnr>=$99)
|
bool @shared a4
|
||||||
txt.print_ub(rnr>=$cc)
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
ubyte wordNr = (rnr >= $33) as ubyte + (rnr >= $66) as ubyte + (rnr >= $99) as ubyte + (rnr >= $CC) as ubyte
|
if a1==0 and a2==0
|
||||||
txt.print_uw(wordNr)
|
cx16.r0++
|
||||||
txt.nl()
|
|
||||||
wordNr = 100 - (rnr >= $33) - (rnr >= $66) - (rnr >= $99) - (rnr >= $CC)
|
if (a1!=0 or a2!=0)==0
|
||||||
txt.print_uw(wordNr)
|
cx16.r0++
|
||||||
txt.nl()
|
|
||||||
|
if a1==0 or a2==0
|
||||||
|
cx16.r0++
|
||||||
|
|
||||||
|
if (a1!=0 and a2!=0)==0
|
||||||
|
cx16.r0++
|
||||||
|
|
||||||
|
|
||||||
|
; if not a1 or not a2
|
||||||
|
; cx16.r0++
|
||||||
|
; if not (a1 and a2)
|
||||||
|
; cx16.r0++
|
||||||
|
; if not a1 and not a2
|
||||||
|
; cx16.r0++
|
||||||
|
; if not (a1 or a2)
|
||||||
|
; cx16.r0++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user