1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-18 02:28:57 +00:00

Constant pointer optimization

This commit is contained in:
Karol Stasiak 2018-03-01 15:57:54 +01:00
parent f8bd496b6b
commit 50b93db337
5 changed files with 73 additions and 1 deletions

View File

@ -133,6 +133,7 @@ object OptimizationPresets {
AlwaysGoodOptimizations.CommonBranchBodyOptimization,
AlwaysGoodOptimizations.CommonExpressionInConditional,
AlwaysGoodOptimizations.CommonIndexSubexpressionElimination,
AlwaysGoodOptimizations.ConstantPointer,
AlwaysGoodOptimizations.ConstantFlowAnalysis,
AlwaysGoodOptimizations.ConstantIndexPropagation,
AlwaysGoodOptimizations.DoubleJumpSimplification,

View File

@ -1395,4 +1395,53 @@ object AlwaysGoodOptimizations {
)
}
// this grows the code by one byte, but shaves 1 cycle and allows for optimizing some stores away
val ConstantPointer = new RuleBasedAssemblyOptimization("Constant pointer optimization",
needsFlowInfo = FlowInfoRequirement.ForwardFlow,
(HasOpcode(STA) & MatchA(0) & HasAddrModeIn(Set(Absolute, ZeroPage)) & MatchParameter(4)) ~
Where(ctx => {
val lo = ctx.get[Constant](4)
ctx.addObject(5, lo + 1)
ctx.addObject(3, ZeroPage)
true
}) ~
(Linear & DoesNotConcernMemoryAt(3,4) & DoesNotConcernMemoryAt(3,5)).* ~
(HasOpcode(STA) & MatchA(1) & HasAddrModeIn(Set(Absolute, ZeroPage)) & MatchParameter(5)) ~
Where(ctx => {
val lo = ctx.get[Int](0) & 0xff
val hi = ctx.get[Int](1) & 0xff
ctx.addObject(2, hi * 256 + lo)
true
}) ~
(Linear & DoesNotConcernMemoryAt(3,4) & DoesNotConcernMemoryAt(3,5)).* ~
(Elidable & MatchParameter(6) & HasAddrModeIn(Set(ZeroPageIndirect, IndexedY))) ~~> { (code, ctx) =>
val addr = ctx.get[Int](2)
val last = code.last
code.init :+ last.copy(parameter = NumericConstant(addr, 2), addrMode = if (last.addrMode == ZeroPageIndirect) Absolute else AbsoluteY)
},
(HasOpcode(STA) & MatchA(0) & HasAddrModeIn(Set(Absolute, ZeroPage)) & MatchParameter(4)) ~
Where(ctx => {
val lo = ctx.get[Constant](4)
ctx.addObject(5, lo + 1)
ctx.addObject(3, ZeroPage)
true
}) ~
(Linear & DoesNotConcernMemoryAt(3,4) & DoesNotConcernMemoryAt(3,5)).* ~
(HasOpcode(STX) & MatchX(1) & HasAddrModeIn(Set(Absolute, ZeroPage)) & MatchParameter(5)) ~
Where(ctx => {
val lo = ctx.get[Int](0) & 0xff
val hi = ctx.get[Int](1) & 0xff
ctx.addObject(2, hi * 256 + lo)
true
}) ~
(Linear & DoesNotConcernMemoryAt(3,4) & DoesNotConcernMemoryAt(3,5)).* ~
(Elidable & MatchParameter(6) & HasAddrModeIn(Set(ZeroPageIndirect, IndexedY))) ~~> { (code, ctx) =>
val addr = ctx.get[Int](2)
val last = code.last
code.init :+ last.copy(parameter = NumericConstant(addr, 2), addrMode = if (last.addrMode == ZeroPageIndirect) Absolute else AbsoluteY)
},
)
}

View File

@ -158,6 +158,7 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
val l = lhs.quickSimplify
val r = rhs.quickSimplify
(l, r) match {
case (CompoundConstant(MathOperator.Shl, HalfWordConstant(c1, true), NumericConstant(8, _)), HalfWordConstant(c2, false)) if operator == MathOperator.Or && c1 == c2 => c1
case (NumericConstant(lv, ls), NumericConstant(rv, rs)) =>
var size = ls max rs
val value = operator match {
@ -233,6 +234,7 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
val That = that
val MinusThat = -that
this match {
case CompoundConstant(Plus, CompoundConstant(Shl, HalfWordConstant(c1, true), NumericConstant(8, _)), HalfWordConstant(c2, false)) if c1 == c2 => c1
case CompoundConstant(Plus, NumericConstant(MinusThat, _), r) => r
case CompoundConstant(Plus, l, NumericConstant(MinusThat, _)) => l
case CompoundConstant(Plus, NumericConstant(x, _), r) => CompoundConstant(Plus, r, NumericConstant(x + that, minimumSize(x + that)))

View File

@ -408,4 +408,24 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
| }
""".stripMargin).readByte(0xc000) should equal(1)
}
test("Constant pointers") {
EmuBenchmarkRun(
"""
|byte output0 @$c000
|byte output1 @$c001
|void main() {
| pointer p
| p = output0.addr
| p[0] = 33
| p = op()
| p[0] = 34
|}
|word op () { return output1.addr }
""".stripMargin
){m =>
m.readByte(0xc000) should equal(33)
m.readByte(0xc001) should equal(34)
}
}
}

View File

@ -15,7 +15,7 @@ object EmuOptimizedInlinedRun extends EmuRun(
OptimizationPresets.Good,
false) {
override def inline: Boolean = true
override def blastProcessing: Boolean = true
override def blastProcessing: Boolean = false
}