public override bool Optimize(OptimizationContext context) { var changed = false; for (var i = context.Count - 1; i >= 0; i--) { var instructionCount = context.Count; var instruction = context[i]; if (instruction.Matches(InstructionType.Jump, out var targetLabel) && context.GetLabelPosition(targetLabel) < i) { var startPosition = context.GetLabelPosition(targetLabel); var endPosition = i; if (context[i + 1].Matches(InstructionType.MarkLabel)) { endPosition++; } var labelMap = new ushort?[context.LabelAllocator]; var maxBoundsCheck = -1; // By default, keep al labels the same for (var j = 0; j < labelMap.Length; j++) { labelMap[j] = (ushort)j; } for (var j = startPosition; j <= endPosition; j++) { if (context[j].Matches(InstructionType.BoundsCheck, out var _, out var offset)) { if (offset > maxBoundsCheck) { maxBoundsCheck = offset; } } else if (context[j].Matches(InstructionType.MarkLabel, out var label)) { // ... except for labels that are marked inside the loop... labelMap[label] = null; } } { if (maxBoundsCheck >= 3 && (!context[startPosition + 1].Matches(InstructionType.BoundsCheck, out var _, out var offset) || offset < maxBoundsCheck)) { var canMakeFastPath = true; for (var j = 0; j < context.Count; j++) { if (context[j].CanJumpToLabel) { if (context[j].Matches(InstructionType.BoundsCheck, out var boundsCheckTargetLabel) && boundsCheckTargetLabel == targetLabel) { canMakeFastPath = false; } else if (j >= startPosition && j <= endPosition && context.GetLabelPosition(context[j].Label) < startPosition || context.GetLabelPosition(context[j].Label) > endPosition) { canMakeFastPath = false; } } else if (j >= startPosition && j <= endPosition && context[j].Type == InstructionType.Call) { foreach (var(_, jumpTarget) in context.FailureLabelMap[context[j].Data2].Mapping) { if (context.GetLabelPosition(jumpTarget) < startPosition || context.GetLabelPosition(jumpTarget) > endPosition) { canMakeFastPath = false; break; } } } } if (canMakeFastPath && context.Backtracer.CheckBounds(startPosition, false, maxBoundsCheck) != Analyzers.EvaluationResult.Fail) { // Create fast path var newInstructions = InstructionHelper.DuplicateLabels(context, context.Skip(startPosition).Take(endPosition - startPosition + 1).ToList(), labelMap).ToList(); var goToSlowPathLabel = context.LabelAllocator++; newInstructions.Insert(1, Instruction.BoundsCheck(goToSlowPathLabel, (short)maxBoundsCheck)); newInstructions.Add(Instruction.MarkLabel(goToSlowPathLabel)); context.InsertRange(startPosition, newInstructions); changed = true; } } } }