tweak some not optimizations

cleanup IR typestring
This commit is contained in:
Irmen de Jong 2024-01-05 15:31:45 +01:00
parent 6d9fccacb1
commit f2daa17b92
12 changed files with 81 additions and 79 deletions

View File

@ -66,7 +66,7 @@ class ExpressionSimplifier(private val program: Program,
)
}
if(elsepart.statements.singleOrNull() is Jump) {
val invertedCondition = invertCondition(ifElse.condition)
val invertedCondition = invertCondition(ifElse.condition, program)
return listOf(
IAstModification.ReplaceNode(ifElse.condition, invertedCondition, ifElse),
IAstModification.InsertAfter(ifElse, truepart, parent as IStatementContainer),
@ -323,7 +323,7 @@ class ExpressionSimplifier(private val program: Program,
return if (test) {
listOf(IAstModification.ReplaceNode(expr, expr.left, parent))
} else {
listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left), parent))
listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left, program), parent))
}
}
}
@ -334,6 +334,22 @@ class ExpressionSimplifier(private val program: Program,
return noModifications
}
override fun after(expr: PrefixExpression, parent: Node): Iterable<IAstModification> {
if(expr.operator=="not") {
// not X <compare> Y -> X <invertedcompare> Y
val binExpr = expr.expression as? BinaryExpression
if(binExpr!=null) {
val invertedOperator = invertedComparisonOperator(binExpr.operator)
if(invertedOperator!=null) {
val inverted = BinaryExpression(binExpr.left, invertedOperator, binExpr.right, binExpr.position)
return listOf(IAstModification.ReplaceNode(expr, inverted, parent))
}
}
}
return noModifications
}
private fun applyAbsorptionLaws(expr: BinaryExpression): Expression? {
val rightB = expr.right as? BinaryExpression
if(rightB!=null) {

View File

@ -120,7 +120,7 @@ class StatementOptimizer(private val program: Program,
return listOf(
IAstModification.ReplaceNode(ifElse.elsepart, newElsePart, ifElse),
IAstModification.ReplaceNode(ifElse.truepart, newTruePart, ifElse),
IAstModification.ReplaceNode(ifElse.condition, invertCondition(ifElse.condition), ifElse)
IAstModification.ReplaceNode(ifElse.condition, invertCondition(ifElse.condition, program), ifElse)
)
}
}

View File

@ -90,6 +90,14 @@ internal class BoolRemover(val program: Program) : AstWalker() {
override fun after(expr: PrefixExpression, parent: Node): Iterable<IAstModification> {
if(expr.operator=="not") {
val binExpr = expr.expression as? BinaryExpression
if(binExpr!=null) {
val invertedOperator = invertedComparisonOperator(binExpr.operator)
if(invertedOperator!=null) {
val inverted = BinaryExpression(binExpr.left, invertedOperator, binExpr.right, binExpr.position)
return listOf(IAstModification.ReplaceNode(expr, inverted, parent))
}
}
val exprDt = expr.expression.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
val nonBoolDt = if(exprDt==DataType.BOOL) DataType.UBYTE else exprDt
val equalZero = BinaryExpression(expr.expression, "==", NumericLiteral(nonBoolDt, 0.0, expr.expression.position), expr.expression.position)

View File

@ -99,7 +99,7 @@ if not CONDITION
val replacement = AnonymousScope(mutableListOf(
loopLabel,
untilLoop.body,
IfElse(invertCondition(untilLoop.condition),
IfElse(invertCondition(untilLoop.condition, program),
AnonymousScope(mutableListOf(program.jumpLabel(loopLabel)), pos),
AnonymousScope(mutableListOf(), pos),
pos)
@ -138,7 +138,7 @@ _after:
val afterLabel = program.makeLabel("afterwhile", pos)
val replacement = AnonymousScope(mutableListOf(
loopLabel,
IfElse(invertCondition(whileLoop.condition),
IfElse(invertCondition(whileLoop.condition, program),
AnonymousScope(mutableListOf(program.jumpLabel(afterLabel)), pos),
AnonymousScope(mutableListOf(), pos),
pos),

View File

@ -45,7 +45,7 @@ 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
return listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left), parent))
return listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left, program), parent))
}
@ -121,10 +121,11 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val
}
}
// all other not(x) --> x==0
// this means that "not" will never occur anywhere again in the ast after this
val replacement = BinaryExpression(expr.expression, "==", NumericLiteral(DataType.UBYTE,0.0, expr.position), expr.position)
return listOf(IAstModification.ReplaceNodeSafe(expr, replacement, parent))
// not simpleX -> simpleX==0
if(expr.expression.isSimple) {
val replacement = BinaryExpression(expr.expression.copy(),"==", NumericLiteral(DataType.UBYTE, 0.0, expr.position), expr.position)
return listOf(IAstModification.ReplaceNodeSafe(expr, replacement, parent))
}
}
return noModifications
}

View File

@ -211,14 +211,12 @@ main {
val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!!
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 3
val value1 = (stmts[1] as Assignment).value as BinaryExpression
val value2 = (stmts[2] as Assignment).value as BinaryExpression
value1.operator shouldBe "=="
value1.left shouldBe instanceOf<ContainmentCheck>()
(value1.right as NumericLiteral).number shouldBe 0.0
value2.operator shouldBe "=="
value2.left shouldBe instanceOf<ContainmentCheck>()
(value2.right as NumericLiteral).number shouldBe 0.0
val value1 = (stmts[1] as Assignment).value as PrefixExpression
val value2 = (stmts[2] as Assignment).value as PrefixExpression
value1.operator shouldBe "not"
value2.operator shouldBe "not"
value1.expression shouldBe instanceOf<ContainmentCheck>()
value2.expression shouldBe instanceOf<ContainmentCheck>()
}
test("const pointer variable indexing works") {

View File

@ -94,8 +94,13 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
private fun datatypeString(dt: DataType): String {
return when (dt) {
in NumericDatatypes -> dt.toString().lowercase()
DataType.BOOL -> "bool"
DataType.UBYTE -> "ubyte"
DataType.BYTE -> "byte"
DataType.UWORD -> "uword"
DataType.WORD -> "word"
DataType.LONG -> "long"
DataType.FLOAT -> "float"
DataType.STR -> "str"
DataType.ARRAY_UB -> "ubyte["
DataType.ARRAY_B -> "byte["
@ -105,7 +110,7 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
DataType.ARRAY_BOOL -> "bool["
DataType.ARRAY_UW_SPLIT -> "@split uword["
DataType.ARRAY_W_SPLIT -> "@split word["
else -> throw IllegalArgumentException("weird dt: $dt")
DataType.UNDEFINED -> throw IllegalArgumentException("wrong dt")
}
}

View File

@ -1257,12 +1257,15 @@ class BuiltinFunctionCall(override var target: IdentifierReference,
override fun inferType(program: Program) = program.builtinFunctions.returnType(name)
}
fun invertCondition(cond: Expression): Expression {
fun invertCondition(cond: Expression, program: Program): Expression {
if(cond is BinaryExpression) {
val invertedOperator = invertedComparisonOperator(cond.operator)
if (invertedOperator != null)
return BinaryExpression(cond.left, invertedOperator, cond.right, cond.position)
}
return PrefixExpression("not", cond, cond.position)
return if(cond.inferType(program).isBool)
PrefixExpression("not", cond, cond.position)
else
BinaryExpression(cond, "==", NumericLiteral(DataType.UBYTE, 0.0, cond.position), cond.position)
}

View File

@ -1,12 +1,6 @@
TODO
====
consolidate the various type-to-string tables, look for: DataType.BOOL -> "bool"
"all other not(x) --> x==0" SOMETIMES if removed, improves code, sometimes it makes it worse.
Find out what is what! (paint)
ALSO: when adding a expr.issimple to that, it crashes with a parent node mismatch error. FIX THAT.
...

View File

@ -105,7 +105,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
xml.writeCharacters("\n")
xml.writeStartElement("PARAMS")
xml.writeCharacters("\n")
child.parameters.forEach { param -> xml.writeCharacters("${getTypeString(param.dt)} ${param.name}\n") }
child.parameters.forEach { param -> xml.writeCharacters("${param.dt.typeString(null)} ${param.name}\n") }
xml.writeEndElement()
xml.writeCharacters("\n")
child.chunks.forEach { chunk ->

View File

@ -1,7 +1,10 @@
package prog8.intermediate
import prog8.code.*
import prog8.code.core.*
import prog8.code.core.DataType
import prog8.code.core.Encoding
import prog8.code.core.ZeropageWish
import prog8.code.core.internedStringsModuleName
// In the Intermediate Representation, all nesting has been removed.
@ -163,23 +166,7 @@ class IRStMemVar(name: String,
}
}
val typeString: String
get() = when (dt) {
DataType.BOOL -> "bool"
DataType.UBYTE -> "ubyte"
DataType.BYTE -> "byte"
DataType.UWORD -> "uword"
DataType.WORD -> "word"
DataType.FLOAT -> "float"
DataType.ARRAY_BOOL -> "bool[$length]"
DataType.ARRAY_UB, DataType.STR -> "ubyte[$length]"
DataType.ARRAY_B -> "byte[$length]"
DataType.ARRAY_UW -> "uword[$length]"
DataType.ARRAY_W -> "word[$length]"
DataType.ARRAY_F -> "float[$length]"
in SplitWordArrayTypes -> throw InternalCompilerException("@split can't be used on memory mapped arrays")
else -> throw InternalCompilerException("weird dt")
}
val typeString: String = dt.typeString(length)
}
class IRStMemorySlab(
@ -220,23 +207,7 @@ class IRStStaticVariable(name: String,
val uninitialized = onetimeInitializationArrayValue==null && onetimeInitializationStringValue==null && onetimeInitializationNumericValue==null
val typeString: String
get() = when (dt) {
DataType.BOOL -> "bool"
DataType.UBYTE -> "ubyte"
DataType.BYTE -> "byte"
DataType.UWORD -> "uword"
DataType.WORD -> "word"
DataType.FLOAT -> "float"
DataType.ARRAY_BOOL -> "bool[$length]"
DataType.ARRAY_UB, DataType.STR -> "ubyte[$length]"
DataType.ARRAY_B -> "byte[$length]"
DataType.ARRAY_UW -> "uword[$length]"
DataType.ARRAY_W -> "word[$length]"
DataType.ARRAY_F -> "float[$length]"
in SplitWordArrayTypes -> throw InternalCompilerException("split array should have been converted to 2 ubyte arrays")
else -> throw InternalCompilerException("weird dt")
}
val typeString: String = dt.typeString(length)
}
class IRStArrayElement(val number: Double?, val addressOfSymbol: String?) {

View File

@ -6,21 +6,27 @@ import prog8.code.left
import prog8.code.right
fun getTypeString(dt : DataType): String = when(dt) {
DataType.BOOL -> "bool"
DataType.UBYTE -> "ubyte"
DataType.BYTE -> "byte"
DataType.UWORD -> "uword"
DataType.WORD -> "word"
DataType.FLOAT -> "float"
DataType.ARRAY_BOOL -> "bool[]"
DataType.ARRAY_UB, DataType.STR -> "ubyte[]"
DataType.ARRAY_B -> "byte[]"
DataType.ARRAY_UW -> "uword[]"
DataType.ARRAY_W -> "word[]"
DataType.ARRAY_F -> "float[]"
in SplitWordArrayTypes -> throw InternalCompilerException("split array should have been converted to 2 ubyte arrays")
else -> throw InternalCompilerException("weird dt")
fun DataType.typeString(length: Int?): String {
val lengthStr = if(length==0) "" else length.toString()
return when (this) {
DataType.BOOL -> "bool"
DataType.UBYTE -> "ubyte"
DataType.BYTE -> "byte"
DataType.UWORD -> "uword"
DataType.WORD -> "word"
DataType.LONG -> "long"
DataType.FLOAT -> "float"
DataType.STR -> "ubyte[$lengthStr]" // here string doesn't exist as a seperate datatype anymore
DataType.ARRAY_BOOL -> "bool[$lengthStr]"
DataType.ARRAY_UB -> "ubyte[$lengthStr]"
DataType.ARRAY_B -> "byte[$lengthStr]"
DataType.ARRAY_UW -> "uword[$lengthStr]"
DataType.ARRAY_W -> "word[$lengthStr]"
DataType.ARRAY_F -> "float[$lengthStr]"
DataType.ARRAY_UW_SPLIT -> "@split uword[$lengthStr]" // should be 2 separate byte arrays by now really
DataType.ARRAY_W_SPLIT -> "@split word[$lengthStr]" // should be 2 separate byte arrays by now really
DataType.UNDEFINED -> throw IllegalArgumentException("wrong dt")
}
}
fun convertIRType(typestr: String): IRDataType? {