mirror of
https://github.com/KarolS/millfork.git
synced 2024-09-10 11:54:30 +00:00
Loop unrolling improvements
This commit is contained in:
parent
45e284bdb1
commit
4d927a8949
@ -21,6 +21,7 @@ object OptimizationPresets {
|
|||||||
AlwaysGoodOptimizations.PointlessLoadAfterLoadOrStore,
|
AlwaysGoodOptimizations.PointlessLoadAfterLoadOrStore,
|
||||||
LaterOptimizations.PointessLoadingForShifting,
|
LaterOptimizations.PointessLoadingForShifting,
|
||||||
AlwaysGoodOptimizations.SimplifiableBitOpsSequence,
|
AlwaysGoodOptimizations.SimplifiableBitOpsSequence,
|
||||||
|
AlwaysGoodOptimizations.SimplifiableIndexChanging,
|
||||||
AlwaysGoodOptimizations.IdempotentDuplicateRemoval,
|
AlwaysGoodOptimizations.IdempotentDuplicateRemoval,
|
||||||
AlwaysGoodOptimizations.BranchInPlaceRemoval,
|
AlwaysGoodOptimizations.BranchInPlaceRemoval,
|
||||||
UnusedLabelRemoval,
|
UnusedLabelRemoval,
|
||||||
@ -179,6 +180,7 @@ object OptimizationPresets {
|
|||||||
AlwaysGoodOptimizations.ReverseFlowAnalysis,
|
AlwaysGoodOptimizations.ReverseFlowAnalysis,
|
||||||
AlwaysGoodOptimizations.SimplifiableBitOpsSequence,
|
AlwaysGoodOptimizations.SimplifiableBitOpsSequence,
|
||||||
AlwaysGoodOptimizations.SimplifiableCondition,
|
AlwaysGoodOptimizations.SimplifiableCondition,
|
||||||
|
AlwaysGoodOptimizations.SimplifiableIndexChanging,
|
||||||
AlwaysGoodOptimizations.SimplifiableStackOperation,
|
AlwaysGoodOptimizations.SimplifiableStackOperation,
|
||||||
AlwaysGoodOptimizations.SmarterShiftingOfWords,
|
AlwaysGoodOptimizations.SmarterShiftingOfWords,
|
||||||
AlwaysGoodOptimizations.SmarterShiftingBytes,
|
AlwaysGoodOptimizations.SmarterShiftingBytes,
|
||||||
|
@ -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",
|
val RemoveNops = new RuleBasedAssemblyOptimization("Removing NOP instructions",
|
||||||
needsFlowInfo = FlowInfoRequirement.NoRequirement,
|
needsFlowInfo = FlowInfoRequirement.NoRequirement,
|
||||||
(Elidable & HasOpcode(NOP)) ~~> (_ => Nil)
|
(Elidable & HasOpcode(NOP)) ~~> (_ => Nil)
|
||||||
|
@ -115,6 +115,19 @@ object LoopUnrolling {
|
|||||||
val increasing = isIncreasing(ctx)
|
val increasing = isIncreasing(ctx)
|
||||||
ctx.get[List[AssemblyLine]](Initialization) ++ (0 until Math.abs(start - end)).flatMap(_ => fixLabels(ctx.get[List[AssemblyLine]](BodyWithStep)))
|
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(LDY) & MatchNumericImmediate(Start)).capture(Initialization) ~
|
||||||
(Elidable & HasOpcode(BEQ) & MatchParameter(Skip)) ~
|
(Elidable & HasOpcode(BEQ) & MatchParameter(Skip)) ~
|
||||||
(Elidable & HasOpcode(LABEL) & MatchParameter(Back)) ~
|
(Elidable & HasOpcode(LABEL) & MatchParameter(Back)) ~
|
||||||
@ -143,5 +156,18 @@ object LoopUnrolling {
|
|||||||
val increasing = isIncreasing(ctx)
|
val increasing = isIncreasing(ctx)
|
||||||
ctx.get[List[AssemblyLine]](Initialization) ++ (0 until Math.abs(start - end)).flatMap(_ => fixLabels(ctx.get[List[AssemblyLine]](BodyWithStep)))
|
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)))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user