mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
improve const-evaluation of builtin expressions
This commit is contained in:
parent
b2c9b7635d
commit
25aad8d7be
@ -22,6 +22,9 @@ class BinExprSplitter(private val program: Program, private val options: Compila
|
|||||||
|
|
||||||
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
|
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
|
||||||
|
|
||||||
|
if(options.compTarget.name == VMTarget.NAME)
|
||||||
|
return noModifications // don't split expressions when targeting the vm codegen, it handles nested expressions well
|
||||||
|
|
||||||
if(assignment.value.inferType(program) istype DataType.FLOAT && !options.optimizeFloatExpressions)
|
if(assignment.value.inferType(program) istype DataType.FLOAT && !options.optimizeFloatExpressions)
|
||||||
return noModifications
|
return noModifications
|
||||||
|
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
package prog8.optimizer
|
package prog8.optimizer
|
||||||
|
|
||||||
import prog8.ast.Node
|
import prog8.ast.*
|
||||||
import prog8.ast.Program
|
|
||||||
import prog8.ast.base.FatalAstException
|
import prog8.ast.base.FatalAstException
|
||||||
import prog8.ast.base.UndefinedSymbolError
|
import prog8.ast.base.UndefinedSymbolError
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.maySwapOperandOrder
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.statements.ForLoop
|
|
||||||
import prog8.ast.statements.VarDecl
|
|
||||||
import prog8.ast.statements.VarDeclType
|
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.code.core.AssociativeOperators
|
import prog8.code.core.AssociativeOperators
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
|
import prog8.compiler.BuiltinFunctions
|
||||||
|
|
||||||
|
|
||||||
class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
||||||
@ -265,7 +262,6 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> {
|
override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> {
|
||||||
// the args of a fuction are constfolded via recursion already.
|
|
||||||
val constvalue = functionCallExpr.constValue(program)
|
val constvalue = functionCallExpr.constValue(program)
|
||||||
return if(constvalue!=null)
|
return if(constvalue!=null)
|
||||||
listOf(IAstModification.ReplaceNode(functionCallExpr, constvalue, parent))
|
listOf(IAstModification.ReplaceNode(functionCallExpr, constvalue, parent))
|
||||||
@ -273,6 +269,14 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
|||||||
noModifications
|
noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun after(bfc: BuiltinFunctionCall, parent: Node): Iterable<IAstModification> {
|
||||||
|
val constvalue = bfc.constValue(program)
|
||||||
|
return if(constvalue!=null)
|
||||||
|
listOf(IAstModification.ReplaceNode(bfc, constvalue, parent))
|
||||||
|
else
|
||||||
|
noModifications
|
||||||
|
}
|
||||||
|
|
||||||
override fun after(forLoop: ForLoop, parent: Node): Iterable<IAstModification> {
|
override fun after(forLoop: ForLoop, parent: Node): Iterable<IAstModification> {
|
||||||
fun adjustRangeDt(rangeFrom: NumericLiteral, targetDt: DataType, rangeTo: NumericLiteral, stepLiteral: NumericLiteral?, range: RangeExpression): RangeExpression? {
|
fun adjustRangeDt(rangeFrom: NumericLiteral, targetDt: DataType, rangeTo: NumericLiteral, stepLiteral: NumericLiteral?, range: RangeExpression): RangeExpression? {
|
||||||
val fromCast = rangeFrom.cast(targetDt)
|
val fromCast = rangeFrom.cast(targetDt)
|
||||||
|
@ -10,6 +10,7 @@ import prog8.ast.statements.*
|
|||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
|
import prog8.compiler.BuiltinFunctions
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
@ -1142,7 +1143,13 @@ class BuiltinFunctionCall(override var target: IdentifierReference,
|
|||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun constValue(program: Program): NumericLiteral? = null
|
override fun constValue(program: Program): NumericLiteral? {
|
||||||
|
val function = BuiltinFunctions.getValue(name)
|
||||||
|
if(function.pure) {
|
||||||
|
return program.builtinFunctions.constValue(name, args, position)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
override fun toString() = "BuiltinFunctionCall(name=$name, pos=$position)"
|
override fun toString() = "BuiltinFunctionCall(name=$name, pos=$position)"
|
||||||
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||||
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
|
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
|
||||||
|
@ -3,17 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- logical.p8 is huge compared to 8.2
|
...
|
||||||
|
|
||||||
- compiling logical.p8 to virtual with optimization generates code that is smaller,
|
|
||||||
but takes many more vm instructions to execute than not-optimized code!?
|
|
||||||
|
|
||||||
- petaxian.prg became quite a bit (150 bytes) larger since 8.2, what causes that
|
|
||||||
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
|
|
||||||
Need help with
|
Need help with
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
@ -25,7 +15,10 @@ 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
|
||||||
|
- 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.
|
||||||
- vm: implement remaining sin/cos functions in math.p8
|
- vm: implement remaining sin/cos functions in math.p8
|
||||||
- vm: somehow deal with asmsubs otherwise the vm IR can't fully encode all of prog8
|
- vm: somehow deal with asmsubs otherwise the vm IR can't fully encode all of prog8
|
||||||
- vm: don't store symbol names in instructions to make optimizing the IR easier? but what about jumps to labels. And it's no longer readable by humans.
|
- vm: don't store symbol names in instructions to make optimizing the IR easier? but what about jumps to labels. And it's no longer readable by humans.
|
||||||
|
@ -45,7 +45,7 @@ zsound_lib:
|
|||||||
|
|
||||||
const ubyte song_bank = 1
|
const ubyte song_bank = 1
|
||||||
const uword song_address = $a000
|
const uword song_address = $a000
|
||||||
const ubyte digi_bank = 5
|
const ubyte digi_bank = 6
|
||||||
const uword digi_address = $a000
|
const uword digi_address = $a000
|
||||||
const ubyte zcm_DIGITAB_size = 8 ; header size
|
const ubyte zcm_DIGITAB_size = 8 ; header size
|
||||||
|
|
||||||
@ -82,8 +82,6 @@ zsound_lib:
|
|||||||
txt.print_uw(zsm_get_music_speed())
|
txt.print_uw(zsm_get_music_speed())
|
||||||
txt.print(" hz\nplaying song! hit enter to also play a digi sample!\n")
|
txt.print(" hz\nplaying song! hit enter to also play a digi sample!\n")
|
||||||
|
|
||||||
; for IRQ based playback instead: cx16.set_irq(&zsm_playIRQ, true)
|
|
||||||
|
|
||||||
repeat {
|
repeat {
|
||||||
if cx16.joystick_get2(0)!=$ffff
|
if cx16.joystick_get2(0)!=$ffff
|
||||||
pcm_trigger_digi(digi_bank, digi_address)
|
pcm_trigger_digi(digi_bank, digi_address)
|
||||||
|
@ -3,6 +3,12 @@
|
|||||||
%import cx16diskio
|
%import cx16diskio
|
||||||
%zpreserved $22,$2d ; zsound lib uses this region
|
%zpreserved $22,$2d ; zsound lib uses this region
|
||||||
|
|
||||||
|
; NOTE: this is a proof of concept to stream ZCM digi from disk while playing.
|
||||||
|
; currently there's no real streaming API / circular buffer in zsound,
|
||||||
|
; so it simply loads the whole ZCM file in chunks in memory sequentially.
|
||||||
|
; But it does so while the playback is going on in the background.
|
||||||
|
; It seems fast enough to stream + play 16khz 16bit stereo samples. (around 64 Kb/sec)
|
||||||
|
; Maybe we can go faster but 22 Khz seemed too much to keep up with.
|
||||||
|
|
||||||
main $0830 {
|
main $0830 {
|
||||||
|
|
||||||
@ -54,7 +60,7 @@ zsound_lib:
|
|||||||
|
|
||||||
pcm_init()
|
pcm_init()
|
||||||
pcm_trigger_digi(digi_bank, digi_address)
|
pcm_trigger_digi(digi_bank, digi_address)
|
||||||
cx16.set_irq(&zsm_playroutine, true)
|
cx16.set_irq(&zsm_playroutine_irq, true)
|
||||||
|
|
||||||
txt.print("\nstreaming from file, playback in irq!\n")
|
txt.print("\nstreaming from file, playback in irq!\n")
|
||||||
uword size = 1
|
uword size = 1
|
||||||
@ -73,7 +79,7 @@ zsound_lib:
|
|||||||
pcm_stop() ;unreached
|
pcm_stop() ;unreached
|
||||||
}
|
}
|
||||||
|
|
||||||
sub zsm_playroutine() {
|
sub zsm_playroutine_irq() {
|
||||||
pcm_play()
|
pcm_play()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user