mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-11 12:29:46 +00:00
Constant pointer optimization
This commit is contained in:
parent
f8bd496b6b
commit
50b93db337
@ -133,6 +133,7 @@ object OptimizationPresets {
|
||||
AlwaysGoodOptimizations.CommonBranchBodyOptimization,
|
||||
AlwaysGoodOptimizations.CommonExpressionInConditional,
|
||||
AlwaysGoodOptimizations.CommonIndexSubexpressionElimination,
|
||||
AlwaysGoodOptimizations.ConstantPointer,
|
||||
AlwaysGoodOptimizations.ConstantFlowAnalysis,
|
||||
AlwaysGoodOptimizations.ConstantIndexPropagation,
|
||||
AlwaysGoodOptimizations.DoubleJumpSimplification,
|
||||
|
@ -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)
|
||||
},
|
||||
)
|
||||
|
||||
}
|
||||
|
2
src/main/scala/millfork/env/Constant.scala
vendored
2
src/main/scala/millfork/env/Constant.scala
vendored
@ -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)))
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user