mirror of
https://github.com/KarolS/millfork.git
synced 2025-03-21 06:30:14 +00:00
Better detection of memset loops (fixes #59)
This commit is contained in:
parent
fe094af912
commit
a92f24b280
@ -231,8 +231,8 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
||||
!env.overlapsVariable(f.variable, source) &&
|
||||
!env.overlapsVariable(f.variable, f.start) &&
|
||||
!env.overlapsVariable(f.variable, f.end) &&
|
||||
source.isPure &&
|
||||
sourceType.size == 1 &&
|
||||
ctx.isConstant(source) &&
|
||||
sourceType.size <= 1 &&
|
||||
targetType.size == 1 &&
|
||||
sourceType.isAssignableTo(targetType)
|
||||
) {
|
||||
@ -738,9 +738,9 @@ object AbstractStatementPreprocessor {
|
||||
val sourceType = AbstractExpressionCompiler.getExpressionType(ctx, source)
|
||||
val targetType = AbstractExpressionCompiler.getExpressionType(ctx, target)
|
||||
if (
|
||||
source.isPure &&
|
||||
index.isPure &&
|
||||
sourceType.size == 1 &&
|
||||
ctx.isConstant(source) &&
|
||||
ctx.isConstant(index) &&
|
||||
sourceType.size <= 1 &&
|
||||
targetType.size == 1 &&
|
||||
sourceType.isAssignableTo(targetType)&&
|
||||
!env.isVolatile(VariableExpression(pointy)) &&
|
||||
|
@ -2,7 +2,7 @@ package millfork.compiler
|
||||
|
||||
import millfork.env.{Environment, Label, NormalFunction, NormalParamSignature}
|
||||
import millfork.error.Logger
|
||||
import millfork.node.NiceFunctionProperty
|
||||
import millfork.node.{Expression, NiceFunctionProperty}
|
||||
import millfork.{CompilationFlag, CompilationOptions, JobContext}
|
||||
|
||||
/**
|
||||
@ -15,6 +15,9 @@ case class CompilationContext(env: Environment,
|
||||
niceFunctionProperties: Set[(NiceFunctionProperty, String)],
|
||||
breakLabels: Map[String, Label] = Map(),
|
||||
continueLabels: Map[String, Label] = Map()){
|
||||
|
||||
def isConstant(v: Expression): Boolean = v.isPure || env.eval(v).isDefined
|
||||
|
||||
def withInlinedEnv(environment: Environment, newLabel: String): CompilationContext = {
|
||||
val newEnv = new Environment(Some(env), newLabel, environment.cpuFamily, options)
|
||||
newEnv.things ++= environment.things
|
||||
|
@ -1292,7 +1292,7 @@ object BuiltIns {
|
||||
def compileByteMultiplication(ctx: CompilationContext, v: Expression, c: Int): List[AssemblyLine] = {
|
||||
c match {
|
||||
case 0 =>
|
||||
if (v.isPure) return List(AssemblyLine.immediate(LDA, 0))
|
||||
if (ctx.isConstant(v)) return List(AssemblyLine.immediate(LDA, 0))
|
||||
else return MosExpressionCompiler.compileToA(ctx, v) ++ List(AssemblyLine.immediate(LDA, 0))
|
||||
case 1 => return MosExpressionCompiler.compileToA(ctx, v)
|
||||
case 2 | 4 | 8 | 16 | 32 =>
|
||||
|
@ -21,7 +21,7 @@ object Z80BulkMemoryOperations {
|
||||
*/
|
||||
def compileMemcpy(ctx: CompilationContext, target: IndexedExpression, source: IndexedExpression, f: ForStatement): List[ZLine] = {
|
||||
val sourceOffset = removeVariableOnce(ctx, f.variable, source.index).getOrElse(return compileForStatement(ctx, f)._1)
|
||||
if (!sourceOffset.isPure) return compileForStatement(ctx, f)._1
|
||||
if (!ctx.isConstant(sourceOffset)) return compileForStatement(ctx, f)._1
|
||||
val sourceIndexExpression = sourceOffset #+# f.start
|
||||
val calculateSource = Z80ExpressionCompiler.calculateAddressToHL(ctx, IndexedExpression(source.name, sourceIndexExpression).pos(source.position), forWriting = false)
|
||||
compileMemoryBulk(ctx, target, f,
|
||||
@ -85,11 +85,11 @@ object Z80BulkMemoryOperations {
|
||||
|
||||
if (ctx.options.flag(CompilationFlag.EmitZ80Opcodes)) {
|
||||
removeVariableOnce(ctx, f.variable, target.index) match {
|
||||
case Some(targetOffset) if targetOffset.isPure =>
|
||||
case Some(targetOffset) if ctx.isConstant(targetOffset) =>
|
||||
return compileForZ80(targetOffset)
|
||||
case _ =>
|
||||
}
|
||||
if (target.isPure && target.name == f.variable && !ctx.env.overlapsVariable(f.variable, target.index)) {
|
||||
if (ctx.isConstant(target) && target.name == f.variable && !ctx.env.overlapsVariable(f.variable, target.index)) {
|
||||
return compileForZ80(target.index)
|
||||
}
|
||||
}
|
||||
@ -437,7 +437,7 @@ object Z80BulkMemoryOperations {
|
||||
val pointy = ctx.env.getPointy(target.name)
|
||||
if (pointy.elementType.alignedSize > 1) return Z80StatementCompiler.compileForStatement(ctx, f)._1
|
||||
val targetOffset = removeVariableOnce(ctx, f.variable, target.index).getOrElse(return compileForStatement(ctx, f)._1)
|
||||
if (!targetOffset.isPure) return compileForStatement(ctx, f)._1
|
||||
if (!ctx.isConstant(targetOffset)) return compileForStatement(ctx, f)._1
|
||||
val indexVariableSize = ctx.env.get[Variable](f.variable).typ.size
|
||||
val wrapper = createForLoopPreconditioningIfStatement(ctx, f)
|
||||
val decreasingDespiteSyntax = preferDecreasing && (f.direction == ForDirection.ParallelTo || f.direction == ForDirection.ParallelUntil)
|
||||
|
Loading…
x
Reference in New Issue
Block a user