1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-02-01 14:31:33 +00:00

Don't optimize accesses to arrays of size 0 and 1 – assume that overruns are deliberate.

This commit is contained in:
Karol Stasiak 2020-07-24 22:25:21 +02:00
parent 9a67ac553d
commit 2ee2de62cd
4 changed files with 19 additions and 11 deletions

View File

@ -437,18 +437,20 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
val shrunkElementSize = targetType.alignedSize >> shifts
val shrunkArraySize = arraySizeInBytes.fold(9999)(_.>>(shifts))
val scaledIndex = arraySizeInBytes match {
case Some(n) if n <= 256 => targetType.alignedSize match {
// "n > targetType.alignedSize" means
// "don't do optimizations on arrays size 0 or 1"
case Some(n) if n > targetType.alignedSize && n <= 256 => targetType.alignedSize match {
case 1 => "byte" <| index
case 2 => "<<" <| ("byte" <| index, LiteralExpression(1, 1))
case 4 => "<<" <| ("byte" <| index, LiteralExpression(2, 1))
case 8 => "<<" <| ("byte" <| index, LiteralExpression(3, 1))
case _ => "*" <| ("byte" <| index, LiteralExpression(targetType.alignedSize, 1))
}
case Some(n) if n <= 512 && targetType.alignedSize == 2 =>
case Some(n) if n > targetType.alignedSize && n <= 512 && targetType.alignedSize == 2 =>
"nonet" <| ("<<" <| ("byte" <| index, LiteralExpression(1, 1)))
case Some(n) if n <= 512 && targetType.alignedSize == 2 =>
case Some(n) if n > targetType.alignedSize && n <= 512 && targetType.alignedSize == 2 =>
"nonet" <| ("<<" <| ("byte" <| index, LiteralExpression(1, 1)))
case Some(_) if shrunkArraySize <= 256 =>
case Some(n) if n > targetType.alignedSize && shrunkArraySize <= 256 =>
"<<" <| ("word" <| ("*" <| ("byte" <| index, LiteralExpression(shrunkElementSize, 1))), LiteralExpression(shifts, 1))
case _ => targetType.alignedSize match {
case 1 => "word" <| index
@ -668,16 +670,18 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
val shrunkElementSize = targetType.alignedSize >> shifts
val shrunkArraySize = arraySizeInBytes.fold(9999)(_.>>(shifts))
val scaledIndex = arraySizeInBytes match {
case Some(n) if n <= 256 => targetType.alignedSize match {
// "n > targetType.alignedSize" means
// "don't do optimizations on arrays size 0 or 1"
case Some(n) if n > targetType.alignedSize && n <= 256 => targetType.alignedSize match {
case 1 => "byte" <| index
case 2 => "<<" <| ("byte" <| index, LiteralExpression(1, 1))
case 4 => "<<" <| ("byte" <| index, LiteralExpression(2, 1))
case 8 => "<<" <| ("byte" <| index, LiteralExpression(3, 1))
case _ => "*" <| ("byte" <| index, LiteralExpression(targetType.alignedSize, 1))
}
case Some(n) if n <= 512 && targetType.alignedSize == 2 =>
case Some(n) if n > targetType.alignedSize && n <= 512 && targetType.alignedSize == 2 =>
"nonet" <| ("<<" <| ("byte" <| index, LiteralExpression(1, 1)))
case Some(_) if shrunkArraySize <= 256 =>
case Some(n) if n > targetType.alignedSize && shrunkArraySize <= 256 =>
"<<" <| ("word" <| ("*" <| ("byte" <| index, LiteralExpression(shrunkElementSize, 1))), LiteralExpression(shifts, 1))
case _ => targetType.alignedSize match {
case 1 => "word" <| index

View File

@ -829,7 +829,8 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
ctx.env.getPointy(aname) match {
case p: VariablePointy => compileToD(ctx, index #*# p.elementType.alignedSize) ++ List(MLine.absolute(ADDD, p.addr), MLine.tfr(M6809Register.D, M6809Register.X))
case p: ConstantPointy =>
if (p.sizeInBytes.exists(_ < 255)) {
// don't optimize arrays of size 0 or 1
if (p.sizeInBytes.exists(_ < 255) && p.elementCount.forall(_ > 1)) {
compileToB(ctx, index #*# p.elementType.alignedSize) ++ List(MLine.immediate(LDX, p.value), MLine.inherent(ABX))
} else {
compileToX(ctx, index #*# p.elementType.alignedSize) :+ MLine.indexedX(LEAX, p.value)

View File

@ -2381,7 +2381,10 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
case _: VariablePointy => return Nil
case p: ConstantPointy => p.sizeInBytes match {
case None => return Nil
case Some(s) => s
case Some(s) =>
// don't do checks on arrays size 0 or 1
if (p.elementCount.exists(_ < 2)) return Nil
s
}
}
ctx.env.eval(index) match {

View File

@ -1404,7 +1404,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
0
}
pointy match {
case ConstantPointy(baseAddr, _, sizeInBytes, _, _, _, alignment, readOnly) =>
case ConstantPointy(baseAddr, _, sizeInBytes, elementCount, _, _, alignment, readOnly) =>
if (forWriting && readOnly) {
ctx.log.error("Writing to a constant array", i.position)
}
@ -1412,7 +1412,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
case (None, offset) => List(ZLine.ldImm16(ZRegister.HL, (baseAddr + extraOffset + offset * elementSize).quickSimplify))
case (Some(index), offset) =>
val constantPart = (baseAddr + extraOffset + offset * elementSize).quickSimplify
if (getExpressionType(ctx, i.index).size == 1 && sizeInBytes.exists(_ < 256) && alignment == WithinPageAlignment) {
if (getExpressionType(ctx, i.index).size == 1 && sizeInBytes.exists(_ < 256) && elementCount.forall(_ > 1) && alignment == WithinPageAlignment) {
compileToA(ctx, i.index) ++ List.fill(logElemSize)(ZLine.register(ADD, ZRegister.A)) ++ List(
ZLine.imm8(ADD, constantPart.loByte),
ZLine.ld8(ZRegister.L, ZRegister.A),