get rid of the noshortcircuit fallback

This commit is contained in:
Irmen de Jong 2024-01-17 21:24:41 +01:00
parent 504d1440cc
commit 69075376dc
12 changed files with 25 additions and 49 deletions

View File

@ -18,7 +18,6 @@ class CompilationOptions(val output: OutputType,
var optimize: Boolean = false, var optimize: Boolean = false,
var asmQuiet: Boolean = false, var asmQuiet: Boolean = false,
var asmListfile: Boolean = false, var asmListfile: Boolean = false,
var shortCircuit: Boolean = true,
var includeSourcelines: Boolean = false, var includeSourcelines: Boolean = false,
var experimentalCodegen: Boolean = false, var experimentalCodegen: Boolean = false,
var varsHighBank: Int? = null, var varsHighBank: Int? = null,

View File

@ -1076,7 +1076,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
return true return true
} }
if(asmgen.options.shortCircuit && (!expr.left.isSimple() && !expr.right.isSimple())) { if(!expr.right.isSimple()) {
// shortcircuit evaluation into A // shortcircuit evaluation into A
val shortcutLabel = asmgen.makeLabel("shortcut") val shortcutLabel = asmgen.makeLabel("shortcut")
when (expr.operator) { when (expr.operator) {
@ -1097,7 +1097,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else -> throw AssemblyError("invalid logical operator") else -> throw AssemblyError("invalid logical operator")
} }
} else { } else {
// normal evaluation into A // normal evaluation into A, it is *likely* shorter and faster because of the simple operands.
assignExpressionToRegister(expr.left, RegisterOrPair.A, false) assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
if(directIntoY(expr.right)) { if(directIntoY(expr.right)) {
assignExpressionToRegister(expr.right, RegisterOrPair.Y, false) assignExpressionToRegister(expr.right, RegisterOrPair.Y, false)

View File

@ -793,7 +793,6 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
} }
private fun inplacemodificationByteVariableWithValue(name: String, dt: DataType, operator: String, value: PtExpression) { private fun inplacemodificationByteVariableWithValue(name: String, dt: DataType, operator: String, value: PtExpression) {
if(asmgen.options.shortCircuit) {
val shortcutLabel = asmgen.makeLabel("shortcut") val shortcutLabel = asmgen.makeLabel("shortcut")
when (operator) { when (operator) {
"and" -> { "and" -> {
@ -804,7 +803,6 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
and $name and $name
sta $name sta $name
$shortcutLabel:""") $shortcutLabel:""")
return
} }
"or" -> { "or" -> {
// short-circuit LEFT or RIGHT --> if LEFT then LEFT else RIGHT // short-circuit LEFT or RIGHT --> if LEFT then LEFT else RIGHT
@ -814,17 +812,10 @@ $shortcutLabel:""")
ora $name ora $name
sta $name sta $name
$shortcutLabel:""") $shortcutLabel:""")
return
} }
} }
} }
// normal evaluation
asmgen.assignExpressionToRegister(value, RegisterOrPair.A, dt in SignedDatatypes)
inplacemodificationRegisterAwithVariableWithSwappedOperands(operator, name, dt in SignedDatatypes)
asmgen.out(" sta $name")
}
private fun inplacemodificationByteVariableWithVariable(name: String, dt: DataType, operator: String, otherName: String) { private fun inplacemodificationByteVariableWithVariable(name: String, dt: DataType, operator: String, otherName: String) {
// note: no logical and/or shortcut here, not worth it due to simple right operand // note: no logical and/or shortcut here, not worth it due to simple right operand
asmgen.out(" lda $name") asmgen.out(" lda $name")

View File

@ -708,7 +708,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: IRDataType, bitwise: Boolean): ExpressionCodeResult { private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: IRDataType, bitwise: Boolean): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
if(!bitwise && codeGen.options.shortCircuit && (!binExpr.left.isSimple() && !binExpr.right.isSimple())) { if(!bitwise && !binExpr.right.isSimple()) {
// short-circuit LEFT and RIGHT --> if LEFT then RIGHT else LEFT (== if !LEFT then LEFT else RIGHT) // short-circuit LEFT and RIGHT --> if LEFT then RIGHT else LEFT (== if !LEFT then LEFT else RIGHT)
val leftTr = translateExpression(binExpr.left) val leftTr = translateExpression(binExpr.left)
addToResult(result, leftTr, leftTr.resultReg, -1) addToResult(result, leftTr, leftTr.resultReg, -1)
@ -737,7 +737,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
private fun operatorOr(binExpr: PtBinaryExpression, vmDt: IRDataType, bitwise: Boolean): ExpressionCodeResult { private fun operatorOr(binExpr: PtBinaryExpression, vmDt: IRDataType, bitwise: Boolean): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
if(!bitwise && codeGen.options.shortCircuit && (!binExpr.left.isSimple() && !binExpr.right.isSimple())) { if(!bitwise && !binExpr.right.isSimple()) {
// short-circuit LEFT or RIGHT --> if LEFT then LEFT else RIGHT // short-circuit LEFT or RIGHT --> if LEFT then LEFT else RIGHT
val leftTr = translateExpression(binExpr.left) val leftTr = translateExpression(binExpr.left)
addToResult(result, leftTr, leftTr.resultReg, -1) addToResult(result, leftTr, leftTr.resultReg, -1)
@ -1011,7 +1011,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
internal fun operatorLogicalAndInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks { internal fun operatorLogicalAndInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(operand) val tr = translateExpression(operand)
if(codeGen.options.shortCircuit && !operand.isSimple()) { if(!operand.isSimple()) {
// short-circuit LEFT and RIGHT --> if LEFT then RIGHT else LEFT (== if !LEFT then LEFT else RIGHT) // short-circuit LEFT and RIGHT --> if LEFT then RIGHT else LEFT (== if !LEFT then LEFT else RIGHT)
val inplaceReg = codeGen.registers.nextFree() val inplaceReg = codeGen.registers.nextFree()
val shortcutLabel = codeGen.createLabelName() val shortcutLabel = codeGen.createLabelName()
@ -1029,7 +1029,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
IRInstruction(Opcode.STOREM, vmDt, reg1=tr.resultReg, labelSymbol = symbol), null) IRInstruction(Opcode.STOREM, vmDt, reg1=tr.resultReg, labelSymbol = symbol), null)
result += IRCodeChunk(shortcutLabel, null) result += IRCodeChunk(shortcutLabel, null)
} else { } else {
// normal evaluation // normal evaluation, it is *likely* shorter and faster because of the simple operands.
addToResult(result, tr, tr.resultReg, -1) addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null) addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, address = knownAddress) IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, address = knownAddress)
@ -1053,7 +1053,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
internal fun operatorLogicalOrInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks { internal fun operatorLogicalOrInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(operand) val tr = translateExpression(operand)
if(codeGen.options.shortCircuit && !operand.isSimple()) { if(!operand.isSimple()) {
// short-circuit LEFT or RIGHT --> if LEFT then LEFT else RIGHT // short-circuit LEFT or RIGHT --> if LEFT then LEFT else RIGHT
val inplaceReg = codeGen.registers.nextFree() val inplaceReg = codeGen.registers.nextFree()
val shortcutLabel = codeGen.createLabelName() val shortcutLabel = codeGen.createLabelName()
@ -1071,6 +1071,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
IRInstruction(Opcode.STOREM, vmDt, reg1=tr.resultReg, labelSymbol = symbol), null) IRInstruction(Opcode.STOREM, vmDt, reg1=tr.resultReg, labelSymbol = symbol), null)
result += IRCodeChunk(shortcutLabel, null) result += IRCodeChunk(shortcutLabel, null)
} else { } else {
// normal evaluation, it is *likely* shorter and faster because of the simple operands.
addToResult(result, tr, tr.resultReg, -1) addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null) addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, address = knownAddress) IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, address = knownAddress)

View File

@ -50,7 +50,6 @@ private fun compileMain(args: Array<String>): Boolean {
val sourceDirs by cli.option(ArgType.String, fullName="srcdirs", description = "list of extra paths, separated with ${File.pathSeparator}, to search in for imported modules").multiple().delimiter(File.pathSeparator) val sourceDirs by cli.option(ArgType.String, fullName="srcdirs", description = "list of extra paths, separated with ${File.pathSeparator}, to search in for imported modules").multiple().delimiter(File.pathSeparator)
val includeSourcelines by cli.option(ArgType.Boolean, fullName = "sourcelines", description = "include original Prog8 source lines in generated asm code") val includeSourcelines by cli.option(ArgType.Boolean, fullName = "sourcelines", description = "include original Prog8 source lines in generated asm code")
val splitWordArrays by cli.option(ArgType.Boolean, fullName = "splitarrays", description = "treat all word arrays as tagged with @split to make them lsb/msb split in memory") val splitWordArrays by cli.option(ArgType.Boolean, fullName = "splitarrays", description = "treat all word arrays as tagged with @split to make them lsb/msb split in memory")
val noShortCircuit by cli.option(ArgType.Boolean, fullName = "noshortcircuit", description = "do not apply McCarthy/short-circuit evaluation to boolean expressions")
val printAst1 by cli.option(ArgType.Boolean, fullName = "printast1", description = "print out the compiler AST") val printAst1 by cli.option(ArgType.Boolean, fullName = "printast1", description = "print out the compiler AST")
val printAst2 by cli.option(ArgType.Boolean, fullName = "printast2", description = "print out the intermediate AST that is used for code generation") val printAst2 by cli.option(ArgType.Boolean, fullName = "printast2", description = "print out the intermediate AST that is used for code generation")
val breakpointCpuInstruction by cli.option(ArgType.Boolean, fullName = "breakinstr", description = "also use a CPU instruction for %breakpoint") val breakpointCpuInstruction by cli.option(ArgType.Boolean, fullName = "breakinstr", description = "also use a CPU instruction for %breakpoint")
@ -151,7 +150,6 @@ private fun compileMain(args: Array<String>): Boolean {
warnSymbolShadowing == true, warnSymbolShadowing == true,
quietAssembler == true, quietAssembler == true,
asmListfile == true, asmListfile == true,
noShortCircuit != true,
includeSourcelines == true, includeSourcelines == true,
experimentalCodegen == true, experimentalCodegen == true,
varsHighBank, varsHighBank,
@ -230,7 +228,6 @@ private fun compileMain(args: Array<String>): Boolean {
warnSymbolShadowing == true, warnSymbolShadowing == true,
quietAssembler == true, quietAssembler == true,
asmListfile == true, asmListfile == true,
noShortCircuit != true,
includeSourcelines == true, includeSourcelines == true,
experimentalCodegen == true, experimentalCodegen == true,
varsHighBank, varsHighBank,

View File

@ -36,7 +36,6 @@ class CompilerArguments(val filepath: Path,
val warnSymbolShadowing: Boolean, val warnSymbolShadowing: Boolean,
val quietAssembler: Boolean, val quietAssembler: Boolean,
val asmListfile: Boolean, val asmListfile: Boolean,
val shortCircuit: Boolean,
val includeSourcelines: Boolean, val includeSourcelines: Boolean,
val experimentalCodegen: Boolean, val experimentalCodegen: Boolean,
val varsHighBank: Int?, val varsHighBank: Int?,
@ -82,7 +81,6 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
optimize = args.optimize optimize = args.optimize
asmQuiet = args.quietAssembler asmQuiet = args.quietAssembler
asmListfile = args.asmListfile asmListfile = args.asmListfile
shortCircuit = args.shortCircuit
includeSourcelines = args.includeSourcelines includeSourcelines = args.includeSourcelines
experimentalCodegen = args.experimentalCodegen experimentalCodegen = args.experimentalCodegen
breakpointCpuInstruction = args.breakpointCpuInstruction breakpointCpuInstruction = args.breakpointCpuInstruction

View File

@ -30,7 +30,6 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat
warnSymbolShadowing = false, warnSymbolShadowing = false,
quietAssembler = true, quietAssembler = true,
asmListfile = false, asmListfile = false,
shortCircuit = true,
includeSourcelines = false, includeSourcelines = false,
experimentalCodegen = false, experimentalCodegen = false,
varsHighBank = null, varsHighBank = null,

View File

@ -28,7 +28,6 @@ class TestCompilerOptionSourcedirs: FunSpec({
warnSymbolShadowing = false, warnSymbolShadowing = false,
quietAssembler = true, quietAssembler = true,
asmListfile = false, asmListfile = false,
shortCircuit = true,
includeSourcelines = false, includeSourcelines = false,
experimentalCodegen = false, experimentalCodegen = false,
varsHighBank = null, varsHighBank = null,

View File

@ -27,7 +27,6 @@ internal fun compileFile(
warnSymbolShadowing = false, warnSymbolShadowing = false,
quietAssembler = true, quietAssembler = true,
asmListfile = false, asmListfile = false,
shortCircuit = true,
includeSourcelines = false, includeSourcelines = false,
experimentalCodegen = false, experimentalCodegen = false,
varsHighBank = null, varsHighBank = null,

View File

@ -202,11 +202,6 @@ One or more .p8 module files
This removes the need to add @split yourself but some programs may fail to compile with This removes the need to add @split yourself but some programs may fail to compile with
this option as not all array operations are implemented yet on split arrays. this option as not all array operations are implemented yet on split arrays.
``-noshortcircuit``
Do *not* apply `McCarthy/short-circuit evaluation <https://en.wikipedia.org/wiki/Short-circuit_evaluation>`_ to boolean expressions.
This is a new feature and changes the behavior of existing programs so it can be turned off again for now.
This toggle will disappear eventually.
``-vm`` ``-vm``
load and run a p8-virt or p8-ir listing in the internal VirtualMachine instead of compiling a prog8 program file.. load and run a p8-virt or p8-ir listing in the internal VirtualMachine instead of compiling a prog8 program file..

View File

@ -13,7 +13,6 @@ Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
Compiler: Compiler:
- get rid of the noshortcircuit fallback option and code.
- instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead. - instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead.
that will allow them to be reused from custom user written assembly code as well. that will allow them to be reused from custom user written assembly code as well.
- Multidimensional arrays and chained indexing, purely as syntactic sugar over regular arrays. - Multidimensional arrays and chained indexing, purely as syntactic sugar over regular arrays.

View File

@ -40,7 +40,6 @@ class RequestParser : Take {
quietAssembler = false, quietAssembler = false,
includeSourcelines = false, includeSourcelines = false,
asmListfile = false, asmListfile = false,
shortCircuit = true,
experimentalCodegen = false, experimentalCodegen = false,
splitWordArrays = false, splitWordArrays = false,
breakpointCpuInstruction = false, breakpointCpuInstruction = false,