fix absorption law optimization, add 2 additional optimizations

This commit is contained in:
Irmen de Jong 2024-02-14 20:58:28 +01:00
parent 58e1864144
commit 01bbc2234e
2 changed files with 44 additions and 5 deletions

View File

@ -402,12 +402,24 @@ class ExpressionSimplifier(private val program: Program,
return expr.left
}
}
else if(expr.operator=="or" && rightB.operator=="or") {
if(expr.left isSameAs rightB.left || expr.left isSameAs rightB.right) {
// a or (a or b) -> a or b
return expr.right
}
}
else if(expr.operator=="and" && rightB.operator=="and") {
if(expr.left isSameAs rightB.left || expr.left isSameAs rightB.right) {
// a and (a and b) -> a and b
return expr.right
}
}
}
val leftB = expr.left as? BinaryExpression
if(leftB!=null) {
// absorption laws: (a and b) or a --> a, (a or b) and a --> a
if(expr.operator=="or" && leftB.operator=="and") {
if(expr.right isSameAs leftB.left || expr.left isSameAs leftB.right) {
if(expr.right isSameAs leftB.left || expr.right isSameAs leftB.right) {
return expr.right
}
}
@ -416,6 +428,18 @@ class ExpressionSimplifier(private val program: Program,
return expr.right
}
}
else if(expr.operator=="or" && leftB.operator=="or") {
if(expr.right isSameAs leftB.left || expr.right isSameAs leftB.right) {
// (a or b) or a -> a or b
return expr.left
}
}
else if(expr.operator=="and" && leftB.operator=="and") {
if(expr.right isSameAs leftB.left || expr.right isSameAs leftB.right) {
// (a and b) or a -> a and b
return expr.left
}
}
}
return null
}

View File

@ -825,16 +825,19 @@ main {
if a and (b or a)
cx16.r0 ++
; no opt:
if a and (b and a)
cx16.r0 ++
if a or (b or a)
cx16.r0 ++
if (b and a) and b
cx16.r0 ++
if (b or a) or b
cx16.r0 ++
}
}"""
val result = compileText(Cx16Target(), true, src, writeAssembly = false)!!
val st = result.compilerAst.entrypoint.statements
st.size shouldBe 10
st.size shouldBe 12
val if1 = st[4] as IfElse
val if2 = st[5] as IfElse
val if3 = st[6] as IfElse
@ -845,8 +848,20 @@ main {
(if4.condition as IdentifierReference).nameInSource shouldBe listOf("a")
val if5 = st[8] as IfElse
val if6 = st[9] as IfElse
if5.condition shouldBe instanceOf<BinaryExpression>()
if6.condition shouldBe instanceOf<BinaryExpression>()
val if7 = st[10] as IfElse
val if8 = st[11] as IfElse
val if5bc = if5.condition as BinaryExpression
val if6bc = if6.condition as BinaryExpression
val if7bc = if7.condition as BinaryExpression
val if8bc = if8.condition as BinaryExpression
if5bc.left shouldBe instanceOf<IdentifierReference>()
if5bc.right shouldBe instanceOf<IdentifierReference>()
if6bc.left shouldBe instanceOf<IdentifierReference>()
if6bc.right shouldBe instanceOf<IdentifierReference>()
if7bc.left shouldBe instanceOf<IdentifierReference>()
if7bc.right shouldBe instanceOf<IdentifierReference>()
if8bc.left shouldBe instanceOf<IdentifierReference>()
if8bc.right shouldBe instanceOf<IdentifierReference>()
}
test("funky bitshifts") {