mirror of
https://github.com/irmen/prog8.git
synced 2025-12-19 20:17:17 +00:00
IR: optimize load+add+load into single loadm with offset (also store)
update gradle wrapper to 9.2.0
This commit is contained in:
@@ -55,6 +55,8 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) {
|
||||
|| cleanupPushPop(chunk1, indexedInstructions)
|
||||
|| simplifyConstantReturns(chunk1, indexedInstructions)
|
||||
|| removeNeedlessLoads(chunk1, indexedInstructions)
|
||||
|| useArrayIndexingInsteadOfAdds(chunk1, indexedInstructions)
|
||||
|| removeNops(chunk1, indexedInstructions) // last time, in case one of the optimizers replaced something with a nop
|
||||
} while (changed)
|
||||
}
|
||||
}
|
||||
@@ -553,4 +555,40 @@ jump p8_label_gen_2
|
||||
}
|
||||
return changed
|
||||
}
|
||||
|
||||
private fun useArrayIndexingInsteadOfAdds(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<IRInstruction>>): Boolean {
|
||||
var changed = false
|
||||
indexedInstructions.reversed().forEach { (idx, ins) ->
|
||||
if (ins.opcode == Opcode.ADD && ins.immediate!=null && idx>0) {
|
||||
val load = indexedInstructions[idx-1].value
|
||||
if((load.opcode==Opcode.LOAD) && load.labelSymbol!=null) {
|
||||
val lastInstruction = indexedInstructions[idx+1].value
|
||||
if(lastInstruction.opcode==Opcode.LOADI) {
|
||||
val targetRegister = lastInstruction.reg1!!
|
||||
if(ins.reg1==lastInstruction.reg2!! && load.reg1==lastInstruction.reg2!!) {
|
||||
val loadm = IRInstruction(Opcode.LOADM, lastInstruction.type, reg1=targetRegister, labelSymbol = load.labelSymbol, symbolOffset = ins.immediate)
|
||||
chunk.instructions[idx-1] = loadm
|
||||
chunk.instructions.removeAt(idx+1)
|
||||
chunk.instructions.removeAt(idx)
|
||||
changed = true
|
||||
}
|
||||
} else if(lastInstruction.opcode==Opcode.STOREI) {
|
||||
val targetRegister = lastInstruction.reg1!!
|
||||
if(ins.reg1==lastInstruction.reg2!! && load.reg1==lastInstruction.reg2!!) {
|
||||
val valueLoad = indexedInstructions[idx-2].value
|
||||
if(valueLoad.opcode==Opcode.LOAD && valueLoad.reg1==targetRegister) {
|
||||
val storem = IRInstruction(Opcode.STOREM, lastInstruction.type, reg1=valueLoad.reg1, labelSymbol = load.labelSymbol, symbolOffset = ins.immediate)
|
||||
chunk.instructions[idx-1] = storem
|
||||
chunk.instructions.removeAt(idx+1)
|
||||
chunk.instructions.removeAt(idx)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
Prog8 compiler v12.0.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit cfa4355a in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-c128.p8
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
Prog8 compiler v12.0.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit cfa4355a in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-c64.p8
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
Prog8 compiler v12.0.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit cfa4355a in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-cx16.p8
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
Prog8 compiler v12.0.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit cfa4355a in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-pet32.p8
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
Prog8 compiler v12.0.1 by Irmen de Jong (irmen@razorvine.net)
|
||||
Prerelease version from git commit cfa4355a in branch master
|
||||
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Compiling program import-all-virtual.p8
|
||||
|
||||
@@ -61,9 +61,8 @@ Future Things and Ideas
|
||||
|
||||
IR/VM
|
||||
-----
|
||||
- optimize away the use of ADD to offset from a label. It's possible to do that with a label-offset in the instruction itself: loadm.b r7,main.start.array2+255 (it works for 255 but after that it starts using ADD!)
|
||||
- get rid of LOADX/STOREX/STOREZX, LOADINDEXED/STOREINDEXED just use add + loadi / storei?
|
||||
- extend the index range from 0-255 to 0-32767 in the LOADX, STOREX, STOREZX, LOADINDEXED, STOREINDEXED etc instructions (not compatible with 8 bit 6502, but the 68000 can use that)
|
||||
- get rid of LOADX/STOREX/STOREZX, LOADINDEXED/STOREINDEXED just use add + loadi / storei?
|
||||
- if float<0 / if word<0 uses sgn or load, but still use a bgt etc instruction after that with a #0 operand even though the sgn and load instructions sets the status bits already, so just use bstneg etc
|
||||
- add and sub instructions should modify the status flags so an explicit compare to zero can be avoided for example: if cx16.r0sL + cx16.r1sL <= 0 now compiles into: addr.b r10,r11 / bgts.b r10,#0,label
|
||||
- getting it in shape for code generation: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
|
||||
|
||||
@@ -26,8 +26,6 @@ main {
|
||||
%ir {{
|
||||
loadm.b r1007,main.start.array2+255
|
||||
storem.b r1007,$ff02
|
||||
loadm.b r1007,main.start.array2+256
|
||||
storem.b r1007,$ff04
|
||||
load.w r1009,main.start.array2
|
||||
add.w r1009,#$0100
|
||||
loadi.b r1008,r1009
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -306,7 +306,7 @@ class IRProgram(val name: String,
|
||||
fun convert(asmChunk: IRInlineAsmChunk): IRCodeChunks {
|
||||
val chunks = mutableListOf<IRCodeChunkBase>()
|
||||
var chunk = IRCodeChunk(asmChunk.label, null)
|
||||
asmChunk.assembly.lineSequence().forEach {
|
||||
asmChunk.assembly.lineSequence().filter{it.isNotBlank()}.forEach {
|
||||
val parsed = parseIRCodeLine(it.trim())
|
||||
parsed.fold(
|
||||
ifLeft = { instruction -> chunk += instruction },
|
||||
|
||||
Reference in New Issue
Block a user