1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-10-09 13:57:05 +00:00

Removed invalid optimization, added bit shifting optimization

This commit is contained in:
Karol Stasiak 2018-02-27 12:01:53 +01:00
parent 51a4fe5859
commit f9835ebf7e
3 changed files with 104 additions and 16 deletions

View File

@ -172,7 +172,8 @@ object OptimizationPresets {
AlwaysGoodOptimizations.ReverseFlowAnalysis,
AlwaysGoodOptimizations.SimplifiableBitOpsSequence,
AlwaysGoodOptimizations.SimplifiableCondition,
AlwaysGoodOptimizations.SmarterShiftingWords,
AlwaysGoodOptimizations.SmarterShiftingOfWords,
AlwaysGoodOptimizations.SmarterShiftingBytes,
AlwaysGoodOptimizations.UnconditionalJumpRemoval,
UnusedLabelRemoval,
AlwaysGoodOptimizations.TailCallOptimization,

View File

@ -825,7 +825,7 @@ object AlwaysGoodOptimizations {
}
}
val SmarterShiftingWords = new RuleBasedAssemblyOptimization("Smarter shifting of words",
val SmarterShiftingOfWords = new RuleBasedAssemblyOptimization("Smarter shifting of words",
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
wordShifting(8, hiFirst = false, hiFromX = true),
wordShifting(8, hiFirst = false, hiFromX = false),
@ -845,6 +845,62 @@ object AlwaysGoodOptimizations {
wordShifting(5, hiFirst = true, hiFromX = false),
)
val SmarterShiftingBytes = new RuleBasedAssemblyOptimization("Smarter shifting of bytes",
needsFlowInfo = FlowInfoRequirement.NoRequirement,
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~~> { _ =>
List(
AssemblyLine.implied(ROR),
AssemblyLine.implied(ROR),
AssemblyLine.immediate(AND, 0x80)
)
},
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~~> { _ =>
List(
AssemblyLine.implied(ROR),
AssemblyLine.implied(ROR),
AssemblyLine.implied(ROR),
AssemblyLine.immediate(AND, 0xC0)
)
},
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~~> { _ =>
List(
AssemblyLine.implied(ROL),
AssemblyLine.implied(ROL),
AssemblyLine.immediate(AND, 0x1)
)
},
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~~> { _ =>
List(
AssemblyLine.implied(ROL),
AssemblyLine.implied(ROL),
AssemblyLine.implied(ROL),
AssemblyLine.immediate(AND, 0x3)
)
},
)
private def carryFlagConversionCase(shift: Int, firstSet: Boolean, zeroIfSet: Boolean) = {
val nonZero = 1 << shift
val test = Elidable & HasOpcode(if (firstSet) BCC else BCS) & MatchParameter(0)
@ -1105,20 +1161,6 @@ object AlwaysGoodOptimizations {
code.take(code.length / 2 + 1)
},
(
(
(HasOpcodeIn(Set(LDA, LAX)) & MatchAddrMode(0) & MatchParameter(1)) ~
HasOpcodeIn(Set(LDY, LDX, AND, ORA, EOR, ADC, SBC, CLC, SEC, CPY, CPX, CMP)).*
).capture(7) ~
blockIsIdempotentWhenItComesToIndexRegisters(7) ~
(HasOpcodeIn(ShortConditionalBranching) & MatchParameter(2)) ~
Not(HasOpcode(LABEL) & MatchParameter(2)).* ~
(HasOpcode(LABEL) & MatchParameter(2))
).capture(3) ~
MatchElidableCopyOf(7, Anything, DoesntMatterWhatItDoesWith(State.C, State.Z, State.N, State.V)) ~~> { (_, ctx) =>
ctx.get[List[AssemblyLine]](3)
},
(Elidable & HasOpcodeIn(Set(LDA, LAX)) & MatchAddrMode(0) & MatchParameter(1)) ~
(Elidable & HasOpcode(AND) & HasAddrModeIn(Set(Absolute, ZeroPage)) & DoesntMatterWhatItDoesWith(State.C, State.V, State.A)) ~
HasOpcodeIn(Set(BEQ, BNE)) ~

View File

@ -363,4 +363,49 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
m.readByte(0xc000) should equal(5)
}
}
test("Common conditions") {
new EmuRun(Cpu.StrictMos,
OptimizationPresets.NodeOpt, List(
LaterOptimizations.PointlessLoadAfterStore,
LaterOptimizations.DoubleLoadToDifferentRegisters,
LaterOptimizations.DoubleLoadToTheSameRegister,
AlwaysGoodOptimizations.PointlessRegisterTransfers,
AlwaysGoodOptimizations.PointlessRegisterTransfersBeforeReturn,
AlwaysGoodOptimizations.PointlessLoadBeforeReturn,
AlwaysGoodOptimizations.PoinlessLoadBeforeAnotherLoad,
AlwaysGoodOptimizations.PointlessRegisterTransfers,
AlwaysGoodOptimizations.PointlessRegisterTransfersBeforeReturn,
AlwaysGoodOptimizations.PointlessRegisterTransfersBeforeReturn,
AlwaysGoodOptimizations.PointlessLoadBeforeReturn,
AlwaysGoodOptimizations.PoinlessLoadBeforeAnotherLoad,
AlwaysGoodOptimizations.PointlessStashingToIndexOverShortSafeBranch,
AlwaysGoodOptimizations.PointlessRegisterTransfersBeforeReturn,
AlwaysGoodOptimizations.IdempotentDuplicateRemoval,
AlwaysGoodOptimizations.IdempotentDuplicateRemoval,
AlwaysGoodOptimizations.IdempotentDuplicateRemoval,
AlwaysGoodOptimizations.CommonExpressionInConditional), false)(
"""
| byte output @$C000
| void main(){
| byte a
| byte b
| output = 0
| a = delta()
| if a == 0 {
| output += 1
| a += 1
| }
| b = a
| if b == 0 {
| output += 1
| a += 1
| }
| }
| byte delta () {
| return 0
| }
""".stripMargin).readByte(0xc000) should equal(1)
}
}