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> {
|
||||
|
||||
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)
|
||||
return noModifications
|
||||
|
||||
|
@ -1,18 +1,15 @@
|
||||
package prog8.optimizer
|
||||
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.*
|
||||
import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.base.UndefinedSymbolError
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.maySwapOperandOrder
|
||||
import prog8.ast.statements.ForLoop
|
||||
import prog8.ast.statements.VarDecl
|
||||
import prog8.ast.statements.VarDeclType
|
||||
import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.code.core.AssociativeOperators
|
||||
import prog8.code.core.DataType
|
||||
import prog8.compiler.BuiltinFunctions
|
||||
|
||||
|
||||
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> {
|
||||
// the args of a fuction are constfolded via recursion already.
|
||||
val constvalue = functionCallExpr.constValue(program)
|
||||
return if(constvalue!=null)
|
||||
listOf(IAstModification.ReplaceNode(functionCallExpr, constvalue, parent))
|
||||
@ -273,6 +269,14 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
||||
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> {
|
||||
fun adjustRangeDt(rangeFrom: NumericLiteral, targetDt: DataType, rangeTo: NumericLiteral, stepLiteral: NumericLiteral?, range: RangeExpression): RangeExpression? {
|
||||
val fromCast = rangeFrom.cast(targetDt)
|
||||
|
@ -10,6 +10,7 @@ import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstVisitor
|
||||
import prog8.code.core.*
|
||||
import prog8.compiler.BuiltinFunctions
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.floor
|
||||
@ -1142,7 +1143,13 @@ class BuiltinFunctionCall(override var target: IdentifierReference,
|
||||
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 accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
|
||||
|
@ -3,17 +3,7 @@ TODO
|
||||
|
||||
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
|
||||
^^^^^^^^^^^^^^
|
||||
@ -25,7 +15,10 @@ 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.
|
||||
- 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: 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 uword song_address = $a000
|
||||
const ubyte digi_bank = 5
|
||||
const ubyte digi_bank = 6
|
||||
const uword digi_address = $a000
|
||||
const ubyte zcm_DIGITAB_size = 8 ; header size
|
||||
|
||||
@ -82,8 +82,6 @@ zsound_lib:
|
||||
txt.print_uw(zsm_get_music_speed())
|
||||
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 {
|
||||
if cx16.joystick_get2(0)!=$ffff
|
||||
pcm_trigger_digi(digi_bank, digi_address)
|
||||
|
@ -3,6 +3,12 @@
|
||||
%import cx16diskio
|
||||
%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 {
|
||||
|
||||
@ -54,7 +60,7 @@ zsound_lib:
|
||||
|
||||
pcm_init()
|
||||
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")
|
||||
uword size = 1
|
||||
@ -73,7 +79,7 @@ zsound_lib:
|
||||
pcm_stop() ;unreached
|
||||
}
|
||||
|
||||
sub zsm_playroutine() {
|
||||
sub zsm_playroutine_irq() {
|
||||
pcm_play()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user