Code/Wasm/Optimize/Peephole/TeeLocalOptimization.cs
using System.Collections.Generic;
using WasmBox.Wasm.Instructions;
namespace WasmBox.Wasm.Optimize {
/// <summary>
/// An optimization that rewrites `set_local x; get_local x` as `tee_local x`.
/// </summary>
public sealed class TeeLocalOptimization : PeepholeOptimization {
private TeeLocalOptimization() { }
/// <summary>
/// The only instance of this optimization.
/// </summary>
public static readonly TeeLocalOptimization Instance = new TeeLocalOptimization();
/// <summary>
/// Tests if the items at the front of the given list of instructions
/// match the peephole optimization; if a match occurs, a nonzero value
/// is returned that indicates the number of instructions at the front
/// of the list of instructions that should be rewritten.
/// </summary>
/// <param name="instructions">
/// The instructions to match against the peephole optimization.
/// </param>
/// <returns>The number of instructions to rewrite.</returns>
public override uint Match(IReadOnlyList<Instruction> instructions) {
if (instructions.Count < 2)
return 0;
var first = instructions[0];
if (first.Op != Operators.SetLocal)
return 0;
var second = instructions[1];
if (second.Op != Operators.GetLocal)
return 0;
var setLocal = Operators.SetLocal.CastInstruction(first);
var getLocal = Operators.GetLocal.CastInstruction(second);
if (setLocal.Immediate == getLocal.Immediate)
return 2;
else
return 0;
}
/// <summary>
/// Rewrites the given sequence of instructions.
/// </summary>
/// <param name="matched">
/// A list of instructions that has been matched and will all be replaced.
/// </param>
/// <returns>The rewritten instructions.</returns>
public override IReadOnlyList<Instruction> Rewrite(IReadOnlyList<Instruction> matched) {
var setLocal = Operators.SetLocal.CastInstruction(matched[0]);
return new Instruction[] { Operators.TeeLocal.Create(setLocal.Immediate) };
}
}
}