mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +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
|
||||
// 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.
|
||||
|
||||
if(options.compTarget.name==VMTarget.NAME) // don't apply this optimization for Vm target
|
||||
return noModifications
|
||||
|
||||
if(!assignment.isAugmentable
|
||||
&& assignment.target.identifier != null
|
||||
&& !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> {
|
||||
val binExpr = ifElse.condition as? BinaryExpression
|
||||
if(binExpr==null || binExpr.operator !in ComparisonOperators) {
|
||||
// if x -> if x!=0, if x+5 -> if x+5 != 0
|
||||
if(binExpr==null) {
|
||||
// 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(
|
||||
ifElse.condition,
|
||||
"!=",
|
||||
|
@ -3,7 +3,7 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
...
|
||||
- bool data type? see below
|
||||
|
||||
|
||||
Need help with
|
||||
@ -16,7 +16,6 @@ Need help with
|
||||
Future Things and Ideas
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
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
|
||||
- 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.
|
||||
@ -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
|
||||
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?
|
||||
--------------
|
||||
|
Loading…
Reference in New Issue
Block a user