1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Loop unrolling improvements

This commit is contained in:
Karol Stasiak 2018-03-16 14:13:24 +01:00
parent 45e284bdb1
commit 4d927a8949
3 changed files with 52 additions and 0 deletions

View File

@ -21,6 +21,7 @@ object OptimizationPresets {
AlwaysGoodOptimizations.PointlessLoadAfterLoadOrStore,
LaterOptimizations.PointessLoadingForShifting,
AlwaysGoodOptimizations.SimplifiableBitOpsSequence,
AlwaysGoodOptimizations.SimplifiableIndexChanging,
AlwaysGoodOptimizations.IdempotentDuplicateRemoval,
AlwaysGoodOptimizations.BranchInPlaceRemoval,
UnusedLabelRemoval,
@ -179,6 +180,7 @@ object OptimizationPresets {
AlwaysGoodOptimizations.ReverseFlowAnalysis,
AlwaysGoodOptimizations.SimplifiableBitOpsSequence,
AlwaysGoodOptimizations.SimplifiableCondition,
AlwaysGoodOptimizations.SimplifiableIndexChanging,
AlwaysGoodOptimizations.SimplifiableStackOperation,
AlwaysGoodOptimizations.SmarterShiftingOfWords,
AlwaysGoodOptimizations.SmarterShiftingBytes,

View File

@ -906,6 +906,30 @@ object AlwaysGoodOptimizations {
},
)
val SimplifiableIndexChanging = new RuleBasedAssemblyOptimization("Simplifiable index changing",
needsFlowInfo = FlowInfoRequirement.NoRequirement,
(Elidable & HasOpcode(LDX) & MatchImmediate(0)) ~
(Linear & Not(ConcernsX) & Not(ReadsNOrZ)).* ~
(Elidable & HasOpcode(DEX)) ~~> { (lines, ctx) =>
lines.init.tail :+ AssemblyLine.immediate(LDX, (ctx.get[Constant](0) + -1).quickSimplify)
},
(Elidable & HasOpcode(LDX) & MatchImmediate(0)) ~
(Linear & Not(ConcernsX) & Not(ReadsNOrZ)).* ~
(Elidable & HasOpcode(INX)) ~~> { (lines, ctx) =>
lines.init.tail :+ AssemblyLine.immediate(LDX, (ctx.get[Constant](0) + 1).quickSimplify)
},
(Elidable & HasOpcode(LDY) & MatchImmediate(0)) ~
(Linear & Not(ConcernsY) & Not(ReadsNOrZ)).* ~
(Elidable & HasOpcode(DEY)) ~~> { (lines, ctx) =>
lines.init.tail :+ AssemblyLine.immediate(LDY, (ctx.get[Constant](0) + -1).quickSimplify)
},
(Elidable & HasOpcode(LDY) & MatchImmediate(0)) ~
(Linear & Not(ConcernsY) & Not(ReadsNOrZ)).* ~
(Elidable & HasOpcode(INY)) ~~> { (lines, ctx) =>
lines.init.tail :+ AssemblyLine.immediate(LDY, (ctx.get[Constant](0) + 1).quickSimplify)
},
)
val RemoveNops = new RuleBasedAssemblyOptimization("Removing NOP instructions",
needsFlowInfo = FlowInfoRequirement.NoRequirement,
(Elidable & HasOpcode(NOP)) ~~> (_ => Nil)

View File

@ -115,6 +115,19 @@ object LoopUnrolling {
val increasing = isIncreasing(ctx)
ctx.get[List[AssemblyLine]](Initialization) ++ (0 until Math.abs(start - end)).flatMap(_ => fixLabels(ctx.get[List[AssemblyLine]](BodyWithStep)))
},
(Elidable & HasOpcode(LDX) & MatchNumericImmediate(Start)).capture(Initialization) ~
(Elidable & HasOpcode(LABEL) & MatchParameter(Back)) ~
((Elidable & HasOpcodeIn(Set(DEX, INX))).capture(Step) ~
(Elidable & Not(HasOpcodeIn(Set(RTS, JSR, RTI, RTL, BNE, CPX, TXA))) & Not(ChangesX)).*.capture(Body)
).capture(BodyWithStep) ~
(Elidable & HasOpcode(CPX) & MatchNumericImmediate(End) | Elidable & HasOpcode(TXA)) ~
(Elidable & HasOpcode(BNE) & MatchParameter(Back)) ~
Where(ctx => isFeasible(ctx, 2, Unrolling.X)) ~~> { (code, ctx) =>
val start = ctx.get[Int](Start)
val end = ctx.getOrDefault[Int](End, 0)
val increasing = isIncreasing(ctx)
ctx.get[List[AssemblyLine]](Initialization) ++ (0 until Math.abs(start - end)).flatMap(_ => fixLabels(ctx.get[List[AssemblyLine]](BodyWithStep)))
},
(Elidable & HasOpcode(LDY) & MatchNumericImmediate(Start)).capture(Initialization) ~
(Elidable & HasOpcode(BEQ) & MatchParameter(Skip)) ~
(Elidable & HasOpcode(LABEL) & MatchParameter(Back)) ~
@ -143,5 +156,18 @@ object LoopUnrolling {
val increasing = isIncreasing(ctx)
ctx.get[List[AssemblyLine]](Initialization) ++ (0 until Math.abs(start - end)).flatMap(_ => fixLabels(ctx.get[List[AssemblyLine]](BodyWithStep)))
},
(Elidable & HasOpcode(LDY) & MatchNumericImmediate(Start)).capture(Initialization) ~
(Elidable & HasOpcode(LABEL) & MatchParameter(Back)) ~
((Elidable & HasOpcodeIn(Set(DEY, INY))).capture(Step) ~
(Elidable & Not(HasOpcodeIn(Set(RTS, JSR, RTI, RTL, BNE, CPY, TYA))) & Not(ChangesY)).*.capture(Body)
).capture(BodyWithStep) ~
(Elidable & HasOpcode(CPY) & MatchNumericImmediate(End) | Elidable & HasOpcode(TYA)) ~
(Elidable & HasOpcode(BNE) & MatchParameter(Back)) ~
Where(ctx => isFeasible(ctx, 2, Unrolling.Y)) ~~> { (code, ctx) =>
val start = ctx.get[Int](Start)
val end = ctx.getOrDefault[Int](End, 0)
val increasing = isIncreasing(ctx)
ctx.get[List[AssemblyLine]](Initialization) ++ (0 until Math.abs(start - end)).flatMap(_ => fixLabels(ctx.get[List[AssemblyLine]](BodyWithStep)))
},
)
}