mirror of
https://github.com/irmen/prog8.git
synced 2024-11-18 19:12:44 +00:00
optimization added: bitwise operations with a negative constant number -> replace the number by its positive 2 complement
This commit is contained in:
parent
8f379e2262
commit
4f5d36a84d
@ -232,58 +232,62 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
|
|||||||
val constFalse = NumericLiteralValue.fromBoolean(false, expr.position)
|
val constFalse = NumericLiteralValue.fromBoolean(false, expr.position)
|
||||||
val newExpr: Expression? = when (expr.operator) {
|
val newExpr: Expression? = when (expr.operator) {
|
||||||
"or" -> {
|
"or" -> {
|
||||||
if ((leftVal != null && leftVal.asBooleanValue) || (rightVal != null && rightVal.asBooleanValue))
|
when {
|
||||||
constTrue
|
leftVal != null && leftVal.asBooleanValue || rightVal != null && rightVal.asBooleanValue -> constTrue
|
||||||
else if (leftVal != null && !leftVal.asBooleanValue)
|
leftVal != null && !leftVal.asBooleanValue -> expr.right
|
||||||
expr.right
|
rightVal != null && !rightVal.asBooleanValue -> expr.left
|
||||||
else if (rightVal != null && !rightVal.asBooleanValue)
|
else -> null
|
||||||
expr.left
|
}
|
||||||
else
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
"and" -> {
|
"and" -> {
|
||||||
if ((leftVal != null && !leftVal.asBooleanValue) || (rightVal != null && !rightVal.asBooleanValue))
|
when {
|
||||||
constFalse
|
leftVal != null && !leftVal.asBooleanValue || rightVal != null && !rightVal.asBooleanValue -> constFalse
|
||||||
else if (leftVal != null && leftVal.asBooleanValue)
|
leftVal != null && leftVal.asBooleanValue -> expr.right
|
||||||
expr.right
|
rightVal != null && rightVal.asBooleanValue -> expr.left
|
||||||
else if (rightVal != null && rightVal.asBooleanValue)
|
else -> null
|
||||||
expr.left
|
}
|
||||||
else
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
"xor" -> {
|
"xor" -> {
|
||||||
if (leftVal != null && !leftVal.asBooleanValue)
|
when {
|
||||||
expr.right
|
leftVal != null && !leftVal.asBooleanValue -> expr.right
|
||||||
else if (rightVal != null && !rightVal.asBooleanValue)
|
rightVal != null && !rightVal.asBooleanValue -> expr.left
|
||||||
expr.left
|
leftVal != null && leftVal.asBooleanValue -> PrefixExpression("not", expr.right, expr.right.position)
|
||||||
else if (leftVal != null && leftVal.asBooleanValue)
|
rightVal != null && rightVal.asBooleanValue -> PrefixExpression("not", expr.left, expr.left.position)
|
||||||
PrefixExpression("not", expr.right, expr.right.position)
|
else -> null
|
||||||
else if (rightVal != null && rightVal.asBooleanValue)
|
|
||||||
PrefixExpression("not", expr.left, expr.left.position)
|
|
||||||
else
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
"|", "^" -> {
|
}
|
||||||
if (leftVal != null && !leftVal.asBooleanValue)
|
"|" -> {
|
||||||
expr.right
|
when {
|
||||||
else if (rightVal != null && !rightVal.asBooleanValue)
|
leftVal?.number==0.0 -> expr.right
|
||||||
expr.left
|
rightVal?.number==0.0 -> expr.left
|
||||||
else {
|
rightIDt.isBytes && rightVal?.number==255.0 -> NumericLiteralValue(DataType.UBYTE, 255.0, rightVal.position)
|
||||||
if(rightIDt.isBytes && (rightVal?.number==-1.0 || rightVal?.number==255.0))
|
rightIDt.isWords && rightVal?.number==65535.0 -> NumericLiteralValue(DataType.UWORD, 65535.0, rightVal.position)
|
||||||
PrefixExpression("~", expr.left, expr.left.position)
|
leftIDt.isBytes && leftVal?.number==255.0 -> NumericLiteralValue(DataType.UBYTE, 255.0, leftVal.position)
|
||||||
else if(rightIDt.isWords && (rightVal?.number==-1.0 || rightVal?.number==65535.0))
|
leftIDt.isWords && leftVal?.number==65535.0 -> NumericLiteralValue(DataType.UWORD, 65535.0, leftVal.position)
|
||||||
PrefixExpression("~", expr.left, expr.left.position)
|
else -> null
|
||||||
else
|
}
|
||||||
null
|
}
|
||||||
|
"^" -> {
|
||||||
|
when {
|
||||||
|
leftVal?.number==0.0 -> expr.right
|
||||||
|
rightVal?.number==0.0 -> expr.left
|
||||||
|
rightIDt.isBytes && rightVal?.number==255.0 -> PrefixExpression("~", expr.left, expr.left.position)
|
||||||
|
rightIDt.isWords && rightVal?.number==65535.0 -> PrefixExpression("~", expr.left, expr.left.position)
|
||||||
|
leftIDt.isBytes && leftVal?.number==255.0 -> PrefixExpression("~", expr.right, expr.right.position)
|
||||||
|
leftIDt.isWords && leftVal?.number==65535.0 -> PrefixExpression("~", expr.right, expr.right.position)
|
||||||
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"&" -> {
|
"&" -> {
|
||||||
if (leftVal != null && !leftVal.asBooleanValue)
|
when {
|
||||||
constFalse
|
leftVal?.number==0.0 -> constFalse
|
||||||
else if (rightVal != null && !rightVal.asBooleanValue)
|
rightVal?.number==0.0 -> constFalse
|
||||||
constFalse
|
rightIDt.isBytes && rightVal?.number==255.0 -> expr.left
|
||||||
else
|
rightIDt.isWords && rightVal?.number==65535.0 -> expr.left
|
||||||
null
|
leftIDt.isBytes && leftVal?.number==255.0 -> expr.right
|
||||||
|
leftIDt.isWords && leftVal?.number==65535.0 -> expr.right
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"*" -> optimizeMultiplication(expr, leftVal, rightVal)
|
"*" -> optimizeMultiplication(expr, leftVal, rightVal)
|
||||||
"/" -> optimizeDivision(expr, leftVal, rightVal)
|
"/" -> optimizeDivision(expr, leftVal, rightVal)
|
||||||
|
@ -46,6 +46,27 @@ class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalk
|
|||||||
val leftDt = expr.left.inferType(program)
|
val leftDt = expr.left.inferType(program)
|
||||||
val rightDt = expr.right.inferType(program)
|
val rightDt = expr.right.inferType(program)
|
||||||
if(leftDt.isKnown && rightDt.isKnown && leftDt!=rightDt) {
|
if(leftDt.isKnown && rightDt.isKnown && leftDt!=rightDt) {
|
||||||
|
|
||||||
|
// convert a negative operand for bitwise operator to the 2's complement positive number instead
|
||||||
|
if(expr.operator in bitwiseOperators && leftDt.isInteger && rightDt.isInteger) {
|
||||||
|
val leftCv = expr.left.constValue(program)
|
||||||
|
if(leftCv!=null && leftCv.number<0) {
|
||||||
|
val value = if(rightDt.isBytes) 256+leftCv.number else 65536+leftCv.number
|
||||||
|
return listOf(IAstModification.ReplaceNode(
|
||||||
|
expr.left,
|
||||||
|
NumericLiteralValue(rightDt.getOr(DataType.UNDEFINED), value, expr.left.position),
|
||||||
|
expr))
|
||||||
|
}
|
||||||
|
val rightCv = expr.right.constValue(program)
|
||||||
|
if(rightCv!=null && rightCv.number<0) {
|
||||||
|
val value = if(leftDt.isBytes) 256+rightCv.number else 65536+rightCv.number
|
||||||
|
return listOf(IAstModification.ReplaceNode(
|
||||||
|
expr.right,
|
||||||
|
NumericLiteralValue(leftDt.getOr(DataType.UNDEFINED), value, expr.right.position),
|
||||||
|
expr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// determine common datatype and add typecast as required to make left and right equal types
|
// determine common datatype and add typecast as required to make left and right equal types
|
||||||
val (commonDt, toFix) = BinaryExpression.commonDatatype(leftDt.getOr(DataType.UNDEFINED), rightDt.getOr(DataType.UNDEFINED), expr.left, expr.operator, expr.right)
|
val (commonDt, toFix) = BinaryExpression.commonDatatype(leftDt.getOr(DataType.UNDEFINED), rightDt.getOr(DataType.UNDEFINED), expr.left, expr.operator, expr.right)
|
||||||
if(toFix!=null) {
|
if(toFix!=null) {
|
||||||
|
@ -14,6 +14,7 @@ val associativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "=
|
|||||||
val comparisonOperators = setOf("==", "!=", "<", ">", "<=", ">=")
|
val comparisonOperators = setOf("==", "!=", "<", ">", "<=", ">=")
|
||||||
val augmentAssignmentOperators = setOf("+", "-", "/", "*", "**", "&", "|", "^", "<<", ">>", "%", "and", "or", "xor")
|
val augmentAssignmentOperators = setOf("+", "-", "/", "*", "**", "&", "|", "^", "<<", ">>", "%", "and", "or", "xor")
|
||||||
val logicalOperators = setOf("and", "or", "xor", "not")
|
val logicalOperators = setOf("and", "or", "xor", "not")
|
||||||
|
val bitwiseOperators = setOf("&", "|", "^")
|
||||||
|
|
||||||
|
|
||||||
sealed class Expression: Node {
|
sealed class Expression: Node {
|
||||||
|
@ -7,7 +7,6 @@ BUG: fix "assignment isAugmented correctness" test
|
|||||||
|
|
||||||
optimize TODO in "Add assignment to initialize with zero" in StatementReorderer
|
optimize TODO in "Add assignment to initialize with zero" in StatementReorderer
|
||||||
optimize TODO in after(assignment) in VariousCleanups
|
optimize TODO in after(assignment) in VariousCleanups
|
||||||
optimize: bitwise operations with a negative constant number -> replace the number by its positive 2 complement
|
|
||||||
optimize: add some more constant folders mentioned in test.p8
|
optimize: add some more constant folders mentioned in test.p8
|
||||||
optimize: there is an optimizations in AsmOptimizer that can only be done correctly
|
optimize: there is an optimizations in AsmOptimizer that can only be done correctly
|
||||||
if it knows about regular ram vs io space ram distinction.
|
if it knows about regular ram vs io space ram distinction.
|
||||||
|
Loading…
Reference in New Issue
Block a user