diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt index 70e004fb2..e5047e6e0 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt @@ -46,7 +46,7 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) { .map { IndexedValue(it.index, it.value) } val changed = removeNops(chunk1, indexedInstructions) || replaceConcatZeroMsbWithExt(chunk1, indexedInstructions) - || removeDoubleLoadsAndStores(chunk1, indexedInstructions) // TODO not yet implemented + || removeDoubleLoadsAndStores(chunk1, indexedInstructions) || removeUselessArithmetic(chunk1, indexedInstructions) || removeNeedlessCompares(chunk1, indexedInstructions) || removeWeirdBranches(chunk1, chunk2, indexedInstructions) @@ -324,14 +324,16 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) { indexedInstructions.reversed().forEach { (idx, ins) -> if(idx>0 && idx<(indexedInstructions.size-1) && ins.opcode==Opcode.CMPI && ins.immediate==0) { val previous = indexedInstructions[idx-1].value - if(previous.opcode in OpcodesThatSetStatusbitsIncludingCarry) { - chunk.instructions.removeAt(idx) - changed = true - } else if(previous.opcode in OpcodesThatSetStatusbitsButNotCarry) { - val next = indexedInstructions[idx+1].value - if(next.opcode !in arrayOf(Opcode.BSTCC, Opcode.BSTCS, Opcode.BSTPOS, Opcode.BSTNEG)) { + if(previous.reg1==ins.reg1) { + if (previous.opcode in OpcodesThatSetStatusbitsIncludingCarry) { chunk.instructions.removeAt(idx) changed = true + } else if (previous.opcode in OpcodesThatSetStatusbitsButNotCarry) { + val next = indexedInstructions[idx + 1].value + if (next.opcode !in arrayOf(Opcode.BSTCC, Opcode.BSTCS, Opcode.BSTPOS, Opcode.BSTNEG)) { + chunk.instructions.removeAt(idx) + changed = true + } } } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index a0487b82d..0e0c2fa05 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,6 +2,10 @@ TODO ==== +PtAst/IR: attempt more complex common subexpression eliminations. + for any "top level" PtExpression enumerate all subexpressions and find commons, replace them by a tempvar + for walking the ast see walkAst() but it should not recurse into the "top level" PtExpression again + ... @@ -10,7 +14,6 @@ Future Things and Ideas Compiler: - get rid of the noshortcircuit fallback option and code. -- What happens when we make all subs return a boolean not as ubyte in A, but in the cpu's Carry flag? - Multidimensional arrays and chained indexing, purely as syntactic sugar over regular arrays. - make a form of "manual generics" possible like: varsub routine(T arg)->T where T is expanded to a specific type (this is already done hardcoded for several of the builtin functions) @@ -36,7 +39,6 @@ Compiler: - ir: for expressions with array indexes that occur multiple times, can we avoid loading them into new virtualregs everytime and just reuse a single virtualreg as indexer? (this is a form of common subexpression elimination) - ir: the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line. maybe another representation is needed once actual codegeneration is done from the IR...? -- PtAst/IR: more complex common subexpression eliminations - [problematic due to using 64tass:] better support for building library programs, where unused .proc shouldn't be deleted from the assembly? Perhaps replace all uses of .proc/.pend/.endproc by .block/.bend will fix that with a compiler flag? But all library code written in asm uses .proc already..... (textual search/replace when writing the actual asm?)