From b2b5b46c0412bfefe0ebaab458440bf7fcdf5882 Mon Sep 17 00:00:00 2001 From: Edwin Hoksberg Date: Mon, 11 Nov 2024 21:20:43 +0100 Subject: [PATCH] Refactor instruction optimizer a bit --- instructions/optimizer.go | 95 +++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/instructions/optimizer.go b/instructions/optimizer.go index f9c735a..07f5ebb 100644 --- a/instructions/optimizer.go +++ b/instructions/optimizer.go @@ -13,58 +13,77 @@ func OptimizeInstructions(instructions []Instruction) []Instruction { performedOptimizations = make([]optimizedBlock, 0) for instructionIndex := 0; instructionIndex < len(instructions); instructionIndex++ { - instruction := instructions[instructionIndex] - instructionType := instruction.Name + // Only try to optimize if we still have at least 2 instructions left to process + if instructionIndex > len(instructions)-2 { + optimizedInstructions = append(optimizedInstructions, instructions[instructionIndex:]...) + break + } - // Only try to optimize if we still have instructions left to process - if len(instructions)-1 == instructionIndex { - optimizedInstructions = append(optimizedInstructions, instruction) + if optimizeClear(instructions, &instructionIndex) { continue } - // Clear instruction optimization (needs at least 3 instructions) - if instructionIndex < len(instructions)-2 { - // [-] - if instructionType == JumpIfZero && - instructions[instructionIndex+1].Name == Decrement && - instructions[instructionIndex+2].Name == JumpUnlessZero { + if optimizeConsecutive(instructions, &instructionIndex) { + continue + } - instruction.Name = Clear + // If we couldn't find any optimizations, just append the instruction and try the next one + optimizedInstructions = append(optimizedInstructions, instructions[instructionIndex]) + } - storeOptimization(&instructionIndex, 2, instruction) - continue - } - } + recalculateJumps(&optimizedInstructions, performedOptimizations) - // Only try to optimize instructions that can be optimized - if !instruction.CanBeOptimized() { - optimizedInstructions = append(optimizedInstructions, instruction) - continue - } + return optimizedInstructions +} - // Check if we have at least one other instruction of the same type coming up - if instructions[instructionIndex+1].Name != instructionType { - optimizedInstructions = append(optimizedInstructions, instruction) - continue - } +func optimizeClear(instructions []Instruction, instructionIndex *int) bool { + instruction := instructions[*instructionIndex] - // Now we know what we have at least one more recurring instruction ahead, - // loop until we find one that isn't the same, or we have reached the end of the instructions to process - recurringInstructions := 1 - for j := 0; true; j++ { - if instructionIndex+j > len(instructions)-1 || instructions[instructionIndex+j].Name != instructionType { - recurringInstructions = j - break - } + // Clear instruction optimization (needs at least 3 instructions) + if *instructionIndex < len(instructions)-2 { + // [-] + if instruction.Name == JumpIfZero && + instructions[*instructionIndex+1].Name == Decrement && + instructions[*instructionIndex+2].Name == JumpUnlessZero { + + instruction.Name = Clear + + storeOptimization(instructionIndex, 2, instruction) + + return true } + } + + return false +} + +func optimizeConsecutive(instructions []Instruction, instructionIndex *int) bool { + instruction := instructions[*instructionIndex] - instruction.Value = recurringInstructions - storeOptimization(&instructionIndex, recurringInstructions-1, instruction) + // Only try to optimize instructions that can be optimized + if !instruction.CanBeOptimized() { + return false } - recalculateJumps(&optimizedInstructions, performedOptimizations) + // Check if we have at least one other instruction of the same type coming up + if instructions[*instructionIndex+1].Name != instruction.Name { + return false + } - return optimizedInstructions + // Now we know what we have at least one more recurring instruction ahead, + // loop until we find one that isn't the same, or we have reached the end of the instructions to process + recurringInstructions := 1 + for j := 0; true; j++ { + if *instructionIndex+j > len(instructions)-1 || instructions[*instructionIndex+j].Name != instruction.Name { + recurringInstructions = j + break + } + } + + instruction.Value = recurringInstructions + storeOptimization(instructionIndex, recurringInstructions-1, instruction) + + return true } func storeOptimization(instructionIndex *int, length int, instruction Instruction) {