mirror of
https://github.com/KarolS/millfork.git
synced 2024-10-25 05:24:11 +00:00
More loop-related optimizations
This commit is contained in:
parent
d29eb6e177
commit
7c4570766a
@ -124,11 +124,13 @@ object OptimizationPresets {
|
|||||||
AlwaysGoodOptimizations.CommonExpressionInConditional,
|
AlwaysGoodOptimizations.CommonExpressionInConditional,
|
||||||
AlwaysGoodOptimizations.ConstantFlowAnalysis,
|
AlwaysGoodOptimizations.ConstantFlowAnalysis,
|
||||||
AlwaysGoodOptimizations.ConstantIndexPropagation,
|
AlwaysGoodOptimizations.ConstantIndexPropagation,
|
||||||
|
AlwaysGoodOptimizations.DoubleJumpSimplification,
|
||||||
EmptyMemoryStoreRemoval,
|
EmptyMemoryStoreRemoval,
|
||||||
AlwaysGoodOptimizations.FlagFlowAnalysis,
|
AlwaysGoodOptimizations.FlagFlowAnalysis,
|
||||||
AlwaysGoodOptimizations.IdempotentDuplicateRemoval,
|
AlwaysGoodOptimizations.IdempotentDuplicateRemoval,
|
||||||
AlwaysGoodOptimizations.ImpossibleBranchRemoval,
|
AlwaysGoodOptimizations.ImpossibleBranchRemoval,
|
||||||
AlwaysGoodOptimizations.IncrementingIndexRegistersAfterTransfer,
|
AlwaysGoodOptimizations.IncrementingIndexRegistersAfterTransfer,
|
||||||
|
AlwaysGoodOptimizations.IndexComparisonOptimization,
|
||||||
AlwaysGoodOptimizations.IndexSequenceOptimization,
|
AlwaysGoodOptimizations.IndexSequenceOptimization,
|
||||||
AlwaysGoodOptimizations.MathOperationOnTwoIdenticalMemoryOperands,
|
AlwaysGoodOptimizations.MathOperationOnTwoIdenticalMemoryOperands,
|
||||||
AlwaysGoodOptimizations.ModificationOfJustWrittenValue,
|
AlwaysGoodOptimizations.ModificationOfJustWrittenValue,
|
||||||
|
@ -966,20 +966,20 @@ object AlwaysGoodOptimizations {
|
|||||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(ROL, ASL)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
(Elidable & HasOpcodeIn(Set(ROL, ASL)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
||||||
(Linear & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
(Linear & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
||||||
(Elidable & HasOpcodeIn(Set(ROL, ASL)) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
(Elidable & HasOpcodeIn(Set(ROL, ASL)) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> { code =>
|
||||||
code.last :: code.drop(2).init
|
code.last :: code.drop(2).init
|
||||||
},
|
},
|
||||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
||||||
(Linear & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
(Linear & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
||||||
(Elidable & HasOpcode(LSR) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
(Elidable & HasOpcode(LSR) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> { code =>
|
||||||
code.last :: code.drop(2).init
|
code.last :: code.drop(2).init
|
||||||
},
|
},
|
||||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
||||||
(Linear & Not(HasOpcode(LSR)) & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
(Linear & Not(HasOpcode(LSR)) & DoesNotConcernMemoryAt(0, 1) & DoesntChangeIndexingInAddrMode(0)).* ~
|
||||||
(Elidable & HasOpcode(LSR) & DoesNotConcernMemoryAt(0, 1)) ~
|
(Elidable & HasOpcode(LSR) & DoesNotConcernMemoryAt(0, 1)) ~
|
||||||
(Elidable & HasOpcode(ROR) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
(Elidable & HasOpcode(ROR) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> { code =>
|
||||||
code.init.last :: code.last :: code.drop(2).init.init
|
code.init.last :: code.last :: code.drop(2).init.init
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -1036,4 +1036,60 @@ object AlwaysGoodOptimizations {
|
|||||||
},
|
},
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private def negate(branch: AssemblyLine) = branch.opcode match {
|
||||||
|
case BEQ => branch.copy(opcode = BNE)
|
||||||
|
case BNE => branch.copy(opcode = BEQ)
|
||||||
|
case BCC => branch.copy(opcode = BCS)
|
||||||
|
case BCS => branch.copy(opcode = BCC)
|
||||||
|
case BVC => branch.copy(opcode = BVS)
|
||||||
|
case BVS => branch.copy(opcode = BVC)
|
||||||
|
case BMI => branch.copy(opcode = BPL)
|
||||||
|
case BPL => branch.copy(opcode = BMI)
|
||||||
|
}
|
||||||
|
|
||||||
|
val DoubleJumpSimplification = new RuleBasedAssemblyOptimization("Double jump simplification",
|
||||||
|
needsFlowInfo = FlowInfoRequirement.JustLabels,
|
||||||
|
((Elidable & HasOpcode(LABEL) & MatchParameter(1)) ~ LinearOrLabel.*).capture(10) ~
|
||||||
|
Where(ctx => ctx.get[List[AssemblyLine]](10).map(_.sizeInBytes).sum < 100) ~
|
||||||
|
(Elidable & HasOpcodeIn(ShortConditionalBranching) & MatchParameter(0)) ~
|
||||||
|
(Elidable & HasOpcode(JMP) & MatchParameter(1)) ~
|
||||||
|
(Elidable & HasOpcode(LABEL) & MatchParameter(0)) ~~> { (code, ctx) =>
|
||||||
|
ctx.get[List[AssemblyLine]](10) ++ List(negate(code(code.length - 3).copy(parameter = ctx.get[Constant](1))), code.last)
|
||||||
|
},
|
||||||
|
((Elidable & HasOpcode(LABEL) & MatchParameter(1)) ~ LinearOrLabel.*).capture(10) ~
|
||||||
|
Where(ctx => ctx.get[List[AssemblyLine]](10).map(_.sizeInBytes).sum < 100) ~
|
||||||
|
(Elidable & HasOpcodeIn(ShortConditionalBranching) & MatchParameter(0)).capture(13) ~
|
||||||
|
((Elidable & Not(MatchParameter(0))).* ~
|
||||||
|
(Elidable & HasOpcode(LABEL) & MatchParameter(0)) ~
|
||||||
|
(Elidable & HasOpcode(JMP) & MatchParameter(1))).capture(11) ~~> { (code, ctx) =>
|
||||||
|
ctx.get[List[AssemblyLine]](10) ++ ctx.get[List[AssemblyLine]](13).map(_.copy(parameter = ctx.get[Constant](1))) ++ ctx.get[List[AssemblyLine]](11)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
val IndexComparisonOptimization = new RuleBasedAssemblyOptimization("Index comparison optimization",
|
||||||
|
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
|
||||||
|
(Elidable & HasOpcodeIn(Set(DEX, INX)) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~
|
||||||
|
(Linear & Not(ConcernsX)).* ~
|
||||||
|
(Elidable & (HasOpcode(TXA) & DoesntMatterWhatItDoesWith(State.A) | HasOpcode(CPX) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.C, State.V))) ~~> { code =>
|
||||||
|
code.tail.init :+ code.head
|
||||||
|
},
|
||||||
|
(Elidable & HasOpcodeIn(Set(DEY, INY)) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~
|
||||||
|
(Linear & Not(ConcernsY)).* ~
|
||||||
|
(Elidable & (HasOpcode(TYA) & DoesntMatterWhatItDoesWith(State.A) | HasOpcode(CPY) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.C, State.V))) ~~> { code =>
|
||||||
|
code.tail.init :+ code.head
|
||||||
|
},
|
||||||
|
(Elidable & HasAddrMode(Implied) & HasOpcodeIn(Set(DEC, INC)) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~
|
||||||
|
(Linear & Not(ConcernsA)).* ~
|
||||||
|
(Elidable & (
|
||||||
|
HasOpcode(TAY) & DoesntMatterWhatItDoesWith(State.Y)
|
||||||
|
| HasOpcode(TAX) & DoesntMatterWhatItDoesWith(State.X)
|
||||||
|
| HasOpcode(EOR) & HasImmediate(0)
|
||||||
|
| HasOpcode(ORA) & HasImmediate(0)
|
||||||
|
| HasOpcode(AND) & HasImmediate(0xff)
|
||||||
|
| HasOpcode(ANC) & HasImmediate(0xff) & DoesntMatterWhatItDoesWith(State.C, State.V)
|
||||||
|
| HasOpcode(CMP) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.C, State.V))) ~~> { code =>
|
||||||
|
code.tail.init :+ code.head
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user