mirror of
https://github.com/irmen/prog8.git
synced 2024-10-25 00:24:16 +00:00
tiny optimization
This commit is contained in:
parent
c51c1da618
commit
fee58e98c5
@ -67,6 +67,10 @@ internal class BeforeAsmAstChanger(val program: Program,
|
|||||||
// Try to replace A = B <operator> Something by A= B, A = A <operator> Something
|
// Try to replace A = B <operator> Something by A= B, A = A <operator> Something
|
||||||
// this triggers the more efficent augmented assignment code generation more often.
|
// this triggers the more efficent augmented assignment code generation more often.
|
||||||
// But it can only be done if the target variable IS NOT OCCURRING AS AN OPERAND ITSELF.
|
// But it can only be done if the target variable IS NOT OCCURRING AS AN OPERAND ITSELF.
|
||||||
|
|
||||||
|
if(options.compTarget.name==VMTarget.NAME) // don't apply this optimization for Vm target
|
||||||
|
return noModifications
|
||||||
|
|
||||||
if(!assignment.isAugmentable
|
if(!assignment.isAugmentable
|
||||||
&& assignment.target.identifier != null
|
&& assignment.target.identifier != null
|
||||||
&& !assignment.target.isIOAddress(options.compTarget.machine)) {
|
&& !assignment.target.isIOAddress(options.compTarget.machine)) {
|
||||||
@ -170,8 +174,35 @@ internal class BeforeAsmAstChanger(val program: Program,
|
|||||||
|
|
||||||
override fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> {
|
override fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> {
|
||||||
val binExpr = ifElse.condition as? BinaryExpression
|
val binExpr = ifElse.condition as? BinaryExpression
|
||||||
if(binExpr==null || binExpr.operator !in ComparisonOperators) {
|
if(binExpr==null) {
|
||||||
// if x -> if x!=0, if x+5 -> if x+5 != 0
|
// if x -> if x!=0
|
||||||
|
val booleanExpr = BinaryExpression(
|
||||||
|
ifElse.condition,
|
||||||
|
"!=",
|
||||||
|
NumericLiteral.optimalInteger(0, ifElse.condition.position),
|
||||||
|
ifElse.condition.position
|
||||||
|
)
|
||||||
|
return listOf(IAstModification.ReplaceNode(ifElse.condition, booleanExpr, ifElse))
|
||||||
|
}
|
||||||
|
|
||||||
|
if(binExpr.operator !in ComparisonOperators) {
|
||||||
|
val constRight = binExpr.right.constValue(program)
|
||||||
|
if(constRight!=null) {
|
||||||
|
if (binExpr.operator == "+") {
|
||||||
|
// if x+5 -> if x != -5
|
||||||
|
val number = NumericLiteral(constRight.type, -constRight.number, constRight.position)
|
||||||
|
val booleanExpr = BinaryExpression(binExpr.left,"!=", number, ifElse.condition.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(ifElse.condition, booleanExpr, ifElse))
|
||||||
|
}
|
||||||
|
else if (binExpr.operator == "-") {
|
||||||
|
// if x-5 -> if x != 5
|
||||||
|
val number = NumericLiteral(constRight.type, constRight.number, constRight.position)
|
||||||
|
val booleanExpr = BinaryExpression(binExpr.left,"!=", number, ifElse.condition.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(ifElse.condition, booleanExpr, ifElse))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if x*5 -> if x*5 != 0
|
||||||
val booleanExpr = BinaryExpression(
|
val booleanExpr = BinaryExpression(
|
||||||
ifElse.condition,
|
ifElse.condition,
|
||||||
"!=",
|
"!=",
|
||||||
|
@ -3,7 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
...
|
- bool data type? see below
|
||||||
|
|
||||||
|
|
||||||
Need help with
|
Need help with
|
||||||
@ -16,7 +16,6 @@ Need help with
|
|||||||
Future Things and Ideas
|
Future Things and Ideas
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
Compiler:
|
Compiler:
|
||||||
- add true 'bool' type that can only be 0 or 1, so that logical expressons don't have to use boolean() all the time on their operands
|
|
||||||
- add some more optimizations in vmPeepholeOptimizer
|
- add some more optimizations in vmPeepholeOptimizer
|
||||||
- vm Instruction needs to know what the read-registers/memory are, and what the write-register/memory is.
|
- vm Instruction needs to know what the read-registers/memory are, and what the write-register/memory is.
|
||||||
this info is needed for more advanced optimizations and later code generation steps.
|
this info is needed for more advanced optimizations and later code generation steps.
|
||||||
@ -80,6 +79,21 @@ Optimizations:
|
|||||||
- when a for loop's loopvariable isn't referenced in the body, and the iterations are known, replace the loop by a repeatloop
|
- when a for loop's loopvariable isn't referenced in the body, and the iterations are known, replace the loop by a repeatloop
|
||||||
but we have no efficient way right now to see if the body references a variable.
|
but we have no efficient way right now to see if the body references a variable.
|
||||||
|
|
||||||
|
BOOL data type?
|
||||||
|
---------------
|
||||||
|
Logical expressions now need to sprinkle boolean() calls on their operands to yield the correct boolean 0 or 1 result.
|
||||||
|
This is inefficient because most of the time the operands already are boolean but the compiler doesn't know this
|
||||||
|
because the type of boolean values is UBYTE (so theoretically the value can be anything from 0 - 255)
|
||||||
|
|
||||||
|
So the idea is to add a true 'bool' type
|
||||||
|
|
||||||
|
- add BOOL datatype
|
||||||
|
- add ARRAY_OF_BOOL array type
|
||||||
|
- assignments to it automatically do boolean() conversion
|
||||||
|
- logical expressions don't wrap operand of this type
|
||||||
|
- bool & 1 -> bool
|
||||||
|
- before codegen, bool type is discarded and it's just UBYTE
|
||||||
|
|
||||||
|
|
||||||
STRUCTS again?
|
STRUCTS again?
|
||||||
--------------
|
--------------
|
||||||
|
Loading…
Reference in New Issue
Block a user