mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +00:00
get rid of 'noreinit' option for now, because it resulted in unreliable code
This commit is contained in:
parent
0ea70ba656
commit
435b9d8973
@ -16,7 +16,6 @@ class CompilationOptions(val output: OutputType,
|
|||||||
var slowCodegenWarnings: Boolean = false,
|
var slowCodegenWarnings: Boolean = false,
|
||||||
var optimize: Boolean = false,
|
var optimize: Boolean = false,
|
||||||
var optimizeFloatExpressions: Boolean = false,
|
var optimizeFloatExpressions: Boolean = false,
|
||||||
var reinitGlobals: Boolean = true,
|
|
||||||
var asmQuiet: Boolean = false,
|
var asmQuiet: Boolean = false,
|
||||||
var asmListfile: Boolean = false,
|
var asmListfile: Boolean = false,
|
||||||
var experimentalCodegen: Boolean = false,
|
var experimentalCodegen: Boolean = false,
|
||||||
|
@ -205,14 +205,7 @@ internal class ProgramAndVarsGen(
|
|||||||
if (initializers.isNotEmpty()) {
|
if (initializers.isNotEmpty()) {
|
||||||
asmgen.out("prog8_init_vars\t.block")
|
asmgen.out("prog8_init_vars\t.block")
|
||||||
initializers.forEach { assign ->
|
initializers.forEach { assign ->
|
||||||
if(options.reinitGlobals) {
|
asmgen.translate(assign)
|
||||||
asmgen.translate(assign)
|
|
||||||
} else {
|
|
||||||
// only re-init zeropage vars because non-zeropage vars will have a statically defined value
|
|
||||||
if(allocator.isZpVar(assign.target.identifier!!.name)) {
|
|
||||||
asmgen.translate(assign)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
asmgen.out(" rts\n .bend")
|
asmgen.out(" rts\n .bend")
|
||||||
}
|
}
|
||||||
|
@ -33,15 +33,13 @@ class IRCodeGen(
|
|||||||
if(options.evalStackBaseAddress!=null)
|
if(options.evalStackBaseAddress!=null)
|
||||||
throw AssemblyError("IR doesn't use eval-stack")
|
throw AssemblyError("IR doesn't use eval-stack")
|
||||||
|
|
||||||
if(options.reinitGlobals) {
|
// collect global variables initializers
|
||||||
// collect global variables initializers
|
program.allBlocks().forEach {
|
||||||
program.allBlocks().forEach {
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
it.children.filterIsInstance<PtAssignment>().forEach { assign -> result += assignmentGen.translate(assign) }
|
||||||
it.children.filterIsInstance<PtAssignment>().forEach { assign -> result += assignmentGen.translate(assign) }
|
result.forEach { chunk ->
|
||||||
result.forEach { chunk ->
|
if (chunk is IRCodeChunk) irProg.addGlobalInits(chunk)
|
||||||
if (chunk is IRCodeChunk) irProg.addGlobalInits(chunk)
|
else throw AssemblyError("only expect code chunk for global inits")
|
||||||
else throw AssemblyError("only expect code chunk for global inits")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental/alternative codegen")
|
val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental/alternative codegen")
|
||||||
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
||||||
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform any optimizations")
|
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform any optimizations")
|
||||||
val dontReinitGlobals by cli.option(ArgType.Boolean, fullName = "noreinit", description = "don't create code to reinitialize globals on multiple runs of the program")
|
|
||||||
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
||||||
val optimizeFloatExpressions by cli.option(ArgType.Boolean, fullName = "optfloatx", description = "optimize float expressions (warning: can increase program size)")
|
val optimizeFloatExpressions by cli.option(ArgType.Boolean, fullName = "optfloatx", description = "optimize float expressions (warning: can increase program size)")
|
||||||
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
||||||
@ -120,7 +119,6 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
filepath,
|
filepath,
|
||||||
dontOptimize != true,
|
dontOptimize != true,
|
||||||
optimizeFloatExpressions == true,
|
optimizeFloatExpressions == true,
|
||||||
dontReinitGlobals != true,
|
|
||||||
dontWriteAssembly != true,
|
dontWriteAssembly != true,
|
||||||
slowCodegenWarnings == true,
|
slowCodegenWarnings == true,
|
||||||
quietAssembler == true,
|
quietAssembler == true,
|
||||||
@ -184,7 +182,6 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
filepath,
|
filepath,
|
||||||
dontOptimize != true,
|
dontOptimize != true,
|
||||||
optimizeFloatExpressions == true,
|
optimizeFloatExpressions == true,
|
||||||
dontReinitGlobals != true,
|
|
||||||
dontWriteAssembly != true,
|
dontWriteAssembly != true,
|
||||||
slowCodegenWarnings == true,
|
slowCodegenWarnings == true,
|
||||||
quietAssembler == true,
|
quietAssembler == true,
|
||||||
|
@ -30,7 +30,6 @@ class CompilationResult(val compilerAst: Program, // deprecated, use codegenAs
|
|||||||
class CompilerArguments(val filepath: Path,
|
class CompilerArguments(val filepath: Path,
|
||||||
val optimize: Boolean,
|
val optimize: Boolean,
|
||||||
val optimizeFloatExpressions: Boolean,
|
val optimizeFloatExpressions: Boolean,
|
||||||
val reinitGlobals: Boolean,
|
|
||||||
val writeAssembly: Boolean,
|
val writeAssembly: Boolean,
|
||||||
val slowCodegenWarnings: Boolean,
|
val slowCodegenWarnings: Boolean,
|
||||||
val quietAssembler: Boolean,
|
val quietAssembler: Boolean,
|
||||||
@ -75,7 +74,6 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
slowCodegenWarnings = args.slowCodegenWarnings
|
slowCodegenWarnings = args.slowCodegenWarnings
|
||||||
optimize = args.optimize
|
optimize = args.optimize
|
||||||
optimizeFloatExpressions = optimizeFloatExpr
|
optimizeFloatExpressions = optimizeFloatExpr
|
||||||
reinitGlobals = args.reinitGlobals
|
|
||||||
asmQuiet = args.quietAssembler
|
asmQuiet = args.quietAssembler
|
||||||
asmListfile = args.asmListfile
|
asmListfile = args.asmListfile
|
||||||
experimentalCodegen = args.experimentalCodegen
|
experimentalCodegen = args.experimentalCodegen
|
||||||
|
@ -36,26 +36,9 @@ internal class BeforeAsmAstChanger(val program: Program,
|
|||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun before(block: Block, parent: Node): Iterable<IAstModification> {
|
|
||||||
// adjust global variables initialization
|
|
||||||
if(!options.reinitGlobals) {
|
|
||||||
block.statements.asSequence().filterIsInstance<VarDecl>().forEach {
|
|
||||||
if(it.type==VarDeclType.VAR) {
|
|
||||||
it.findInitializer(program)?.let { initializer ->
|
|
||||||
it.value = initializer.value // put the init value back into the vardecl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return noModifications
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||||
if(options.reinitGlobals) {
|
if (decl.type == VarDeclType.VAR && decl.value != null && decl.datatype in NumericDatatypes)
|
||||||
if (decl.type == VarDeclType.VAR && decl.value != null && decl.datatype in NumericDatatypes)
|
throw InternalCompilerException("vardecls for variables, with initial numerical value, should have been rewritten as plain vardecl + assignment $decl")
|
||||||
throw InternalCompilerException("vardecls for variables, with initial numerical value, should have been rewritten as plain vardecl + assignment $decl")
|
|
||||||
}
|
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat
|
|||||||
filepath,
|
filepath,
|
||||||
optimize,
|
optimize,
|
||||||
optimizeFloatExpressions = true,
|
optimizeFloatExpressions = true,
|
||||||
reinitGlobals = true,
|
|
||||||
writeAssembly = true,
|
writeAssembly = true,
|
||||||
slowCodegenWarnings = false,
|
slowCodegenWarnings = false,
|
||||||
quietAssembler = true,
|
quietAssembler = true,
|
||||||
|
@ -44,7 +44,6 @@ class TestCompilerOptionSourcedirs: FunSpec({
|
|||||||
filepath = filePath,
|
filepath = filePath,
|
||||||
optimize = false,
|
optimize = false,
|
||||||
optimizeFloatExpressions = false,
|
optimizeFloatExpressions = false,
|
||||||
reinitGlobals = true,
|
|
||||||
writeAssembly = true,
|
writeAssembly = true,
|
||||||
slowCodegenWarnings = false,
|
slowCodegenWarnings = false,
|
||||||
quietAssembler = true,
|
quietAssembler = true,
|
||||||
|
@ -25,7 +25,6 @@ internal fun compileFile(
|
|||||||
filepath,
|
filepath,
|
||||||
optimize,
|
optimize,
|
||||||
optimizeFloatExpressions = optFloatExpr,
|
optimizeFloatExpressions = optFloatExpr,
|
||||||
reinitGlobals = true,
|
|
||||||
writeAssembly = writeAssembly,
|
writeAssembly = writeAssembly,
|
||||||
slowCodegenWarnings = false,
|
slowCodegenWarnings = false,
|
||||||
quietAssembler = true,
|
quietAssembler = true,
|
||||||
|
@ -136,11 +136,6 @@ One or more .p8 module files
|
|||||||
Don't perform any code optimizations.
|
Don't perform any code optimizations.
|
||||||
Useful for debugging or faster compilation cycles.
|
Useful for debugging or faster compilation cycles.
|
||||||
|
|
||||||
``-noreinit``
|
|
||||||
Don't create code to reinitialize the global (block level) variables on every run of the program.
|
|
||||||
When using this option, it is often no longer be possible to run the program correctly more than once,
|
|
||||||
however, the program may be a bit shorter as a result.
|
|
||||||
|
|
||||||
``-optfloatx``
|
``-optfloatx``
|
||||||
Also optimize float expressions if optimizations are enabled.
|
Also optimize float expressions if optimizations are enabled.
|
||||||
Warning: can increase program size significantly if a lot of floating point expressions are used.
|
Warning: can increase program size significantly if a lot of floating point expressions are used.
|
||||||
|
@ -34,7 +34,6 @@ class RequestParser : Take {
|
|||||||
Path(a),
|
Path(a),
|
||||||
optimize = true,
|
optimize = true,
|
||||||
optimizeFloatExpressions = false,
|
optimizeFloatExpressions = false,
|
||||||
reinitGlobals = true,
|
|
||||||
writeAssembly = true,
|
writeAssembly = true,
|
||||||
slowCodegenWarnings = true,
|
slowCodegenWarnings = true,
|
||||||
compilationTarget = "c64",
|
compilationTarget = "c64",
|
||||||
|
@ -82,7 +82,6 @@ class IRFileReader {
|
|||||||
var zeropage = ZeropageType.FULL
|
var zeropage = ZeropageType.FULL
|
||||||
val zpReserved = mutableListOf<UIntRange>()
|
val zpReserved = mutableListOf<UIntRange>()
|
||||||
var loadAddress = target.machine.PROGRAM_LOAD_ADDRESS
|
var loadAddress = target.machine.PROGRAM_LOAD_ADDRESS
|
||||||
var reInitGlobals = true
|
|
||||||
var optimize = true
|
var optimize = true
|
||||||
var evalStackBaseAddress: UInt? = null
|
var evalStackBaseAddress: UInt? = null
|
||||||
var outputDir = Path("")
|
var outputDir = Path("")
|
||||||
@ -105,7 +104,6 @@ class IRFileReader {
|
|||||||
"launcher" -> launcher = CbmPrgLauncherType.valueOf(value)
|
"launcher" -> launcher = CbmPrgLauncherType.valueOf(value)
|
||||||
"zeropage" -> zeropage = ZeropageType.valueOf(value)
|
"zeropage" -> zeropage = ZeropageType.valueOf(value)
|
||||||
"loadAddress" -> loadAddress = value.toUInt()
|
"loadAddress" -> loadAddress = value.toUInt()
|
||||||
"reinitGlobals" -> reInitGlobals = value.toBoolean()
|
|
||||||
"evalStackBaseAddress" -> evalStackBaseAddress = if(value=="null") null else parseIRValue(value).toUInt()
|
"evalStackBaseAddress" -> evalStackBaseAddress = if(value=="null") null else parseIRValue(value).toUInt()
|
||||||
"zpReserved" -> {
|
"zpReserved" -> {
|
||||||
val (zpstart, zpend) = value.split(',')
|
val (zpstart, zpend) = value.split(',')
|
||||||
@ -129,8 +127,7 @@ class IRFileReader {
|
|||||||
loadAddress,
|
loadAddress,
|
||||||
evalStackBaseAddress = evalStackBaseAddress,
|
evalStackBaseAddress = evalStackBaseAddress,
|
||||||
outputDir = outputDir,
|
outputDir = outputDir,
|
||||||
optimize = optimize,
|
optimize = optimize
|
||||||
reinitGlobals = reInitGlobals
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +22,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
writeVariables()
|
writeVariables()
|
||||||
|
|
||||||
out.write("\n<INITGLOBALS>\n")
|
out.write("\n<INITGLOBALS>\n")
|
||||||
if(irProgram.options.reinitGlobals) {
|
writeCodeChunk(irProgram.globalInits)
|
||||||
// this a code that re-loads startup values into all global (block-level) variables.
|
|
||||||
writeCodeChunk(irProgram.globalInits)
|
|
||||||
}
|
|
||||||
out.write("</INITGLOBALS>\n")
|
out.write("</INITGLOBALS>\n")
|
||||||
writeBlocks()
|
writeBlocks()
|
||||||
out.write("</PROGRAM>\n")
|
out.write("</PROGRAM>\n")
|
||||||
@ -130,7 +127,6 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
}
|
}
|
||||||
out.write("loadAddress=${irProgram.options.loadAddress.toHex()}\n")
|
out.write("loadAddress=${irProgram.options.loadAddress.toHex()}\n")
|
||||||
out.write("optimize=${irProgram.options.optimize}\n")
|
out.write("optimize=${irProgram.options.optimize}\n")
|
||||||
out.write("reinitGlobals=${irProgram.options.reinitGlobals}\n")
|
|
||||||
out.write("evalStackBaseAddress=${irProgram.options.evalStackBaseAddress?.toHex()}\n")
|
out.write("evalStackBaseAddress=${irProgram.options.evalStackBaseAddress?.toHex()}\n")
|
||||||
out.write("outputDir=${irProgram.options.outputDir.toAbsolutePath()}\n")
|
out.write("outputDir=${irProgram.options.outputDir.toAbsolutePath()}\n")
|
||||||
// other options not yet useful here?
|
// other options not yet useful here?
|
||||||
|
@ -48,7 +48,6 @@ output=PRG
|
|||||||
launcher=BASIC
|
launcher=BASIC
|
||||||
zeropage=KERNALSAFE
|
zeropage=KERNALSAFE
|
||||||
loadAddress=0
|
loadAddress=0
|
||||||
reinitGlobals=false
|
|
||||||
evalStackBaseAddress=null
|
evalStackBaseAddress=null
|
||||||
</OPTIONS>
|
</OPTIONS>
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package prog8.vm
|
package prog8.vm
|
||||||
|
|
||||||
import prog8.code.core.*
|
import prog8.code.core.ArrayDatatypes
|
||||||
|
import prog8.code.core.AssemblyError
|
||||||
|
import prog8.code.core.DataType
|
||||||
import prog8.intermediate.*
|
import prog8.intermediate.*
|
||||||
|
|
||||||
class VmProgramLoader {
|
class VmProgramLoader {
|
||||||
@ -15,10 +17,8 @@ class VmProgramLoader {
|
|||||||
|
|
||||||
varsToMemory(irProgram, allocations, variableAddresses, memory)
|
varsToMemory(irProgram, allocations, variableAddresses, memory)
|
||||||
|
|
||||||
if(irProgram.options.reinitGlobals) {
|
if(irProgram.globalInits.isNotEmpty())
|
||||||
if(irProgram.globalInits.isNotEmpty())
|
programChunks += irProgram.globalInits
|
||||||
programChunks += irProgram.globalInits
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure that if there is a "main.start" entrypoint, we jump to it
|
// make sure that if there is a "main.start" entrypoint, we jump to it
|
||||||
irProgram.blocks.firstOrNull()?.let {
|
irProgram.blocks.firstOrNull()?.let {
|
||||||
@ -196,16 +196,6 @@ class VmProgramLoader {
|
|||||||
else -> throw IRParseException("invalid dt")
|
else -> throw IRParseException("invalid dt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if(!program.options.reinitGlobals) {
|
|
||||||
// variable is not initialized as part of a global reinitialization, so we clear it here
|
|
||||||
when(variable.dt) {
|
|
||||||
in ByteDatatypes -> memory.setUB(addr, 0u)
|
|
||||||
in WordDatatypes -> memory.setUW(addr, 0u)
|
|
||||||
DataType.FLOAT -> memory.setFloat(addr, 0.0f)
|
|
||||||
else -> throw IRParseException("invalid dt")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user