/*
 * Copyright 2022 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/sksl/codegen/SkSLRasterPipelineBuilder.h"

#ifdef SK_ENABLE_SKSL_IN_RASTER_PIPELINE

#include "include/core/SkStream.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkArenaAlloc.h"
#include "src/core/SkOpts.h"
#include "src/core/SkRasterPipelineContextUtils.h"
#include "src/core/SkRasterPipelineOpContexts.h"
#include "src/core/SkRasterPipelineOpList.h"
#include "src/core/SkTHash.h"
#include "src/sksl/SkSLPosition.h"
#include "src/sksl/SkSLString.h"
#include "src/sksl/tracing/SkSLDebugTracePriv.h"
#include "src/sksl/tracing/SkSLTraceHook.h"
#include "src/utils/SkBitSet.h"

#if !defined(SKSL_STANDALONE)
#include "src/core/SkRasterPipeline.h"
#endif

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstring>
#include <iterator>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

using namespace skia_private;

namespace SkSL::RP {

#define ALL_SINGLE_SLOT_UNARY_OP_CASES  \
         BuilderOp::acos_float:         \
    case BuilderOp::asin_float:         \
    case BuilderOp::atan_float:         \
    case BuilderOp::cos_float:          \
    case BuilderOp::exp_float:          \
    case BuilderOp::exp2_float:         \
    case BuilderOp::log_float:          \
    case BuilderOp::log2_float:         \
    case BuilderOp::sin_float:          \
    case BuilderOp::sqrt_float:         \
    case BuilderOp::tan_float

#define ALL_MULTI_SLOT_UNARY_OP_CASES        \
         BuilderOp::abs_int:                 \
    case BuilderOp::cast_to_float_from_int:  \
    case BuilderOp::cast_to_float_from_uint: \
    case BuilderOp::cast_to_int_from_float:  \
    case BuilderOp::cast_to_uint_from_float: \
    case BuilderOp::ceil_float:              \
    case BuilderOp::floor_float:             \
    case BuilderOp::invsqrt_float

#define ALL_N_WAY_BINARY_OP_CASES   \
         BuilderOp::atan2_n_floats: \
    case BuilderOp::pow_n_floats

#define ALL_MULTI_SLOT_BINARY_OP_CASES  \
         BuilderOp::add_n_floats:       \
    case BuilderOp::add_n_ints:         \
    case BuilderOp::sub_n_floats:       \
    case BuilderOp::sub_n_ints:         \
    case BuilderOp::mul_n_floats:       \
    case BuilderOp::mul_n_ints:         \
    case BuilderOp::div_n_floats:       \
    case BuilderOp::div_n_ints:         \
    case BuilderOp::div_n_uints:        \
    case BuilderOp::bitwise_and_n_ints: \
    case BuilderOp::bitwise_or_n_ints:  \
    case BuilderOp::bitwise_xor_n_ints: \
    case BuilderOp::mod_n_floats:       \
    case BuilderOp::min_n_floats:       \
    case BuilderOp::min_n_ints:         \
    case BuilderOp::min_n_uints:        \
    case BuilderOp::max_n_floats:       \
    case BuilderOp::max_n_ints:         \
    case BuilderOp::max_n_uints:        \
    case BuilderOp::cmple_n_floats:     \
    case BuilderOp::cmple_n_ints:       \
    case BuilderOp::cmple_n_uints:      \
    case BuilderOp::cmplt_n_floats:     \
    case BuilderOp::cmplt_n_ints:       \
    case BuilderOp::cmplt_n_uints:      \
    case BuilderOp::cmpeq_n_floats:     \
    case BuilderOp::cmpeq_n_ints:       \
    case BuilderOp::cmpne_n_floats:     \
    case BuilderOp::cmpne_n_ints

#define ALL_IMMEDIATE_BINARY_OP_CASES    \
         BuilderOp::add_imm_float:       \
    case BuilderOp::add_imm_int:         \
    case BuilderOp::mul_imm_float:       \
    case BuilderOp::mul_imm_int:         \
    case BuilderOp::bitwise_and_imm_int: \
    case BuilderOp::bitwise_xor_imm_int: \
    case BuilderOp::min_imm_float:       \
    case BuilderOp::max_imm_float:       \
    case BuilderOp::cmple_imm_float:     \
    case BuilderOp::cmple_imm_int:       \
    case BuilderOp::cmple_imm_uint:      \
    case BuilderOp::cmplt_imm_float:     \
    case BuilderOp::cmplt_imm_int:       \
    case BuilderOp::cmplt_imm_uint:      \
    case BuilderOp::cmpeq_imm_float:     \
    case BuilderOp::cmpeq_imm_int:       \
    case BuilderOp::cmpne_imm_float:     \
    case BuilderOp::cmpne_imm_int

#define ALL_IMMEDIATE_MULTI_SLOT_BINARY_OP_CASES \
         BuilderOp::bitwise_and_imm_int

#define ALL_N_WAY_TERNARY_OP_CASES       \
         BuilderOp::smoothstep_n_floats

#define ALL_MULTI_SLOT_TERNARY_OP_CASES \
         BuilderOp::mix_n_floats:       \
    case BuilderOp::mix_n_ints

static bool is_immediate_op(BuilderOp op) {
    switch (op) {
        case ALL_IMMEDIATE_BINARY_OP_CASES: return true;
        default:                            return false;
    }
}

static bool is_multi_slot_immediate_op(BuilderOp op) {
    switch (op) {
        case ALL_IMMEDIATE_MULTI_SLOT_BINARY_OP_CASES: return true;
        default:                                       return false;
    }
}

static BuilderOp convert_n_way_op_to_immediate(BuilderOp op, int slots, int32_t* constantValue) {
    // We rely on the exact ordering of SkRP ops here; the immediate-mode op must always come
    // directly before the n-way op. (If we have more than one, the increasing-slot variations
    // continue backwards from there.)
    BuilderOp immOp = (BuilderOp)((int)op - 1);

    // Some immediate ops support multiple slots.
    if (is_multi_slot_immediate_op(immOp)) {
        return immOp;
    }

    // Most immediate ops only support a single slot.
    if (slots == 1) {
        if (is_immediate_op(immOp)) {
            return immOp;
        }

        // We also allow for immediate-mode subtraction, by adding a negative value.
        switch (op) {
            case BuilderOp::sub_n_ints:
                *constantValue *= -1;
                return BuilderOp::add_imm_int;

            case BuilderOp::sub_n_floats: {
                // This negates the floating-point value by inverting its sign bit.
                *constantValue ^= 0x80000000;
                return BuilderOp::add_imm_float;
            }
            default:
                break;
        }
    }

    // We don't have an immediate-mode version of this op.
    return op;
}

void Builder::unary_op(BuilderOp op, int32_t slots) {
    switch (op) {
        case ALL_SINGLE_SLOT_UNARY_OP_CASES:
        case ALL_MULTI_SLOT_UNARY_OP_CASES:
            fInstructions.push_back({op, {}, slots});
            break;

        default:
            SkDEBUGFAIL("not a unary op");
            break;
    }
}

void Builder::binary_op(BuilderOp op, int32_t slots) {
    if (!fInstructions.empty()) {
        // If we just pushed or splatted a constant onto the stack...
        Instruction& lastInstruction = fInstructions.back();
        if (lastInstruction.fOp == BuilderOp::push_constant && lastInstruction.fImmA >= slots) {
            // ... and this op has an immediate-mode equivalent...
            int32_t constantValue = lastInstruction.fImmB;
            BuilderOp immOp = convert_n_way_op_to_immediate(op, slots, &constantValue);
            if (immOp != op) {
                // ... discard the constants from the stack, and use an immediate-mode op.
                this->discard_stack(slots);
                fInstructions.push_back({immOp, {}, slots, constantValue});
                return;
            }
        }
    }

    switch (op) {
        case ALL_N_WAY_BINARY_OP_CASES:
        case ALL_MULTI_SLOT_BINARY_OP_CASES:
            fInstructions.push_back({op, {}, slots});
            break;

        default:
            SkDEBUGFAIL("not a binary op");
            break;
    }
}

void Builder::ternary_op(BuilderOp op, int32_t slots) {
    switch (op) {
        case ALL_N_WAY_TERNARY_OP_CASES:
        case ALL_MULTI_SLOT_TERNARY_OP_CASES:
            fInstructions.push_back({op, {}, slots});
            break;

        default:
            SkDEBUGFAIL("not a ternary op");
            break;
    }
}

void Builder::dot_floats(int32_t slots) {
    switch (slots) {
        case 1: fInstructions.push_back({BuilderOp::mul_n_floats, {}, slots}); break;
        case 2: fInstructions.push_back({BuilderOp::dot_2_floats, {}, slots}); break;
        case 3: fInstructions.push_back({BuilderOp::dot_3_floats, {}, slots}); break;
        case 4: fInstructions.push_back({BuilderOp::dot_4_floats, {}, slots}); break;

        default:
            SkDEBUGFAIL("invalid number of slots");
            break;
    }
}

void Builder::refract_floats() {
    fInstructions.push_back({BuilderOp::refract_4_floats, {}});
}

void Builder::inverse_matrix(int32_t n) {
    switch (n) {
        case 2:  fInstructions.push_back({BuilderOp::inverse_mat2, {}, 4});  break;
        case 3:  fInstructions.push_back({BuilderOp::inverse_mat3, {}, 9});  break;
        case 4:  fInstructions.push_back({BuilderOp::inverse_mat4, {}, 16}); break;
        default: SkUNREACHABLE;
    }
}

void Builder::pad_stack(int32_t count) {
    if (count > 0) {
        fInstructions.push_back({BuilderOp::pad_stack, {}, count});
    }
}

bool Builder::simplifyImmediateUnmaskedOp() {
    if (fInstructions.size() < 3) {
        return false;
    }

    // If we detect a pattern of 'push, immediate-op, unmasked pop', then we can
    // convert it into an immediate-op directly onto the value slots and take the
    // stack entirely out of the equation.
    Instruction& popInstruction  = fInstructions.back();
    Instruction& immInstruction  = fInstructions.fromBack(1);
    Instruction& pushInstruction = fInstructions.fromBack(2);

    // If the last instruction is an unmasked pop...
    if (popInstruction.fOp == BuilderOp::copy_stack_to_slots_unmasked) {
        // ... and the prior instruction was an immediate-mode op, with the same number of slots...
        if (is_immediate_op(immInstruction.fOp) && immInstruction.fImmA == popInstruction.fImmA) {
            // ... and we support multiple-slot immediates (if this op calls for it)...
            if (immInstruction.fImmA == 1 || is_multi_slot_immediate_op(immInstruction.fOp)) {
                // ... and the prior instruction was `push_slots` of at least that many slots...
                if (pushInstruction.fOp == BuilderOp::push_slots &&
                    pushInstruction.fImmA >= popInstruction.fImmA) {
                    // ... onto the same slot range...
                    Slot immSlot = popInstruction.fSlotA + popInstruction.fImmA;
                    Slot pushSlot = pushInstruction.fSlotA + pushInstruction.fImmA;
                    if (immSlot == pushSlot) {
                        // ... we can shrink the push, eliminate the pop, and perform the immediate
                        // op in-place instead.
                        pushInstruction.fImmA -= immInstruction.fImmA;
                        immInstruction.fSlotA = immSlot - immInstruction.fImmA;
                        fInstructions.pop_back();
                        return true;
                    }
                }
            }
        }
    }

    return false;
}

void Builder::discard_stack(int32_t count) {
    // If we pushed something onto the stack and then immediately discarded part of it, we can
    // shrink or eliminate the push.
    while (count > 0 && !fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        switch (lastInstruction.fOp) {
            case BuilderOp::discard_stack:
                // Our last op was actually a separate discard_stack; combine the discards.
                lastInstruction.fImmA += count;
                return;

            case BuilderOp::push_constant:
            case BuilderOp::push_clone:
            case BuilderOp::push_clone_from_stack:
            case BuilderOp::push_clone_indirect_from_stack:
            case BuilderOp::push_slots:
            case BuilderOp::push_slots_indirect:
            case BuilderOp::push_uniform:
            case BuilderOp::push_uniform_indirect:
            case BuilderOp::pad_stack: {
                // Our last op was a multi-slot push; these cancel out. Eliminate the op if its
                // count reached zero.
                int cancelOut = std::min(count, lastInstruction.fImmA);
                count                 -= cancelOut;
                lastInstruction.fImmA -= cancelOut;
                if (lastInstruction.fImmA == 0) {
                    fInstructions.pop_back();
                }
                continue;
            }
            case BuilderOp::push_condition_mask:
            case BuilderOp::push_loop_mask:
            case BuilderOp::push_return_mask:
                // Our last op was a single-slot push; cancel out one discard and eliminate the op.
                --count;
                fInstructions.pop_back();
                continue;

            case BuilderOp::copy_stack_to_slots_unmasked: {
                // Look for a pattern of `push, immediate-ops, pop` and simplify it down to an
                // immediate-op directly to the value slot.
                if (count == 1) {
                    if (this->simplifyImmediateUnmaskedOp()) {
                        return;
                    }
                }

                // A `copy_stack_to_slots_unmasked` op, followed immediately by a `discard_stack`
                // op with an equal number of slots, is interpreted as an unmasked stack pop.
                // We can simplify pops in a variety of ways. First, temporarily get rid of
                // `copy_stack_to_slots_unmasked`.
                if (count == lastInstruction.fImmA) {
                    SlotRange dst{lastInstruction.fSlotA, lastInstruction.fImmA};
                    fInstructions.pop_back();

                    // See if we can write this pop in a simpler way.
                    this->simplifyPopSlotsUnmasked(&dst);

                    // If simplification consumed the entire range, we're done!
                    if (dst.count == 0) {
                        return;
                    }

                    // Simplification did not consume the entire range. We are still responsible for
                    // copying-back and discarding any remaining slots.
                    this->copy_stack_to_slots_unmasked(dst);
                    count = dst.count;
                }
                break;
            }
            default:
                break;
        }

        // This instruction wasn't a push.
        break;
    }

    if (count > 0) {
        fInstructions.push_back({BuilderOp::discard_stack, {}, count});
    }
}

void Builder::label(int labelID) {
    SkASSERT(labelID >= 0 && labelID < fNumLabels);

    // If the previous instruction was a branch to this label, it's a no-op; jumping to the very
    // next instruction is effectively meaningless.
    while (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();
        switch (lastInstruction.fOp) {
            case BuilderOp::jump:
            case BuilderOp::branch_if_all_lanes_active:
            case BuilderOp::branch_if_any_lanes_active:
            case BuilderOp::branch_if_no_lanes_active:
            case BuilderOp::branch_if_no_active_lanes_on_stack_top_equal:
                if (lastInstruction.fImmA == labelID) {
                    fInstructions.pop_back();
                    continue;
                }
                break;

            default:
                break;
        }
        break;
    }
    fInstructions.push_back({BuilderOp::label, {}, labelID});
}

void Builder::jump(int labelID) {
    SkASSERT(labelID >= 0 && labelID < fNumLabels);
    if (!fInstructions.empty() && fInstructions.back().fOp == BuilderOp::jump) {
        // The previous instruction was also `jump`, so this branch could never possibly occur.
        return;
    }
    fInstructions.push_back({BuilderOp::jump, {}, labelID});
}

void Builder::branch_if_any_lanes_active(int labelID) {
    if (!this->executionMaskWritesAreEnabled()) {
        this->jump(labelID);
        return;
    }

    SkASSERT(labelID >= 0 && labelID < fNumLabels);
    if (!fInstructions.empty() &&
        (fInstructions.back().fOp == BuilderOp::branch_if_any_lanes_active ||
         fInstructions.back().fOp == BuilderOp::jump)) {
        // The previous instruction was `jump` or `branch_if_any_lanes_active`, so this branch
        // could never possibly occur.
        return;
    }
    fInstructions.push_back({BuilderOp::branch_if_any_lanes_active, {}, labelID});
}

void Builder::branch_if_all_lanes_active(int labelID) {
    if (!this->executionMaskWritesAreEnabled()) {
        this->jump(labelID);
        return;
    }

    SkASSERT(labelID >= 0 && labelID < fNumLabels);
    if (!fInstructions.empty() &&
        (fInstructions.back().fOp == BuilderOp::branch_if_all_lanes_active ||
         fInstructions.back().fOp == BuilderOp::jump)) {
        // The previous instruction was `jump` or `branch_if_all_lanes_active`, so this branch
        // could never possibly occur.
        return;
    }
    fInstructions.push_back({BuilderOp::branch_if_all_lanes_active, {}, labelID});
}

void Builder::branch_if_no_lanes_active(int labelID) {
    if (!this->executionMaskWritesAreEnabled()) {
        return;
    }

    SkASSERT(labelID >= 0 && labelID < fNumLabels);
    if (!fInstructions.empty() &&
        (fInstructions.back().fOp == BuilderOp::branch_if_no_lanes_active ||
         fInstructions.back().fOp == BuilderOp::jump)) {
        // The previous instruction was `jump` or `branch_if_no_lanes_active`, so this branch
        // could never possibly occur.
        return;
    }
    fInstructions.push_back({BuilderOp::branch_if_no_lanes_active, {}, labelID});
}

void Builder::branch_if_no_active_lanes_on_stack_top_equal(int value, int labelID) {
    SkASSERT(labelID >= 0 && labelID < fNumLabels);
    if (!fInstructions.empty() &&
        (fInstructions.back().fOp == BuilderOp::jump ||
         (fInstructions.back().fOp == BuilderOp::branch_if_no_active_lanes_on_stack_top_equal &&
          fInstructions.back().fImmB == value))) {
        // The previous instruction was `jump` or `branch_if_no_active_lanes_on_stack_top_equal`
        // (checking against the same value), so this branch could never possibly occur.
        return;
    }
    fInstructions.push_back({BuilderOp::branch_if_no_active_lanes_on_stack_top_equal,
                             {}, labelID, value});
}

void Builder::push_slots(SlotRange src) {
    SkASSERT(src.count >= 0);
    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        // If the previous instruction was pushing slots contiguous to this range, we can collapse
        // the two pushes into one larger push.
        if (lastInstruction.fOp == BuilderOp::push_slots &&
            lastInstruction.fSlotA + lastInstruction.fImmA == src.index) {
            lastInstruction.fImmA += src.count;
            src.count = 0;
        }
    }

    if (src.count > 0) {
        fInstructions.push_back({BuilderOp::push_slots, {src.index}, src.count});
    }

    // Look for a sequence of "copy stack to X, discard stack, copy X to stack". This is a common
    // pattern when multiple operations in a row affect the same variable. When we see this, we can
    // eliminate both the discard and the push.
    if (fInstructions.size() >= 3 && fInstructions.back().fOp == BuilderOp::push_slots) {
        int pushIndex = fInstructions.back().fSlotA;
        int pushCount = fInstructions.back().fImmA;

        const Instruction& discardInst     = fInstructions.fromBack(1);
        const Instruction& copyToSlotsInst = fInstructions.fromBack(2);

        // Look for a `discard_stack` matching our push count.
        if (discardInst.fOp == BuilderOp::discard_stack && discardInst.fImmA == pushCount) {
            // Look for a `copy_stack_to_slots` matching our push.
            if ((copyToSlotsInst.fOp == BuilderOp::copy_stack_to_slots ||
                 copyToSlotsInst.fOp == BuilderOp::copy_stack_to_slots_unmasked) &&
                copyToSlotsInst.fSlotA == pushIndex &&
                copyToSlotsInst.fImmA  == pushCount) {
                // We found a matching sequence. Remove the discard and push.
                fInstructions.pop_back();
                fInstructions.pop_back();
                return;
            }
        }
    }
}

void Builder::push_slots_indirect(SlotRange fixedRange, int dynamicStackID, SlotRange limitRange) {
    // SlotA: fixed-range start
    // SlotB: limit-range end
    // immA: number of slots
    // immB: dynamic stack ID
    fInstructions.push_back({BuilderOp::push_slots_indirect,
                             {fixedRange.index, limitRange.index + limitRange.count},
                             fixedRange.count,
                             dynamicStackID});
}

void Builder::push_uniform(SlotRange src) {
    SkASSERT(src.count >= 0);
    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        // If the previous instruction was pushing uniforms contiguous to this range, we can
        // collapse the two pushes into one larger push.
        if (lastInstruction.fOp == BuilderOp::push_uniform &&
            lastInstruction.fSlotA + lastInstruction.fImmA == src.index) {
            lastInstruction.fImmA += src.count;
            return;
        }
    }

    if (src.count > 0) {
        fInstructions.push_back({BuilderOp::push_uniform, {src.index}, src.count});
    }
}

void Builder::push_uniform_indirect(SlotRange fixedRange,
                                    int dynamicStackID,
                                    SlotRange limitRange) {
    // SlotA: fixed-range start
    // SlotB: limit-range end
    // immA: number of slots
    // immB: dynamic stack ID
    fInstructions.push_back({BuilderOp::push_uniform_indirect,
                             {fixedRange.index, limitRange.index + limitRange.count},
                             fixedRange.count,
                             dynamicStackID});
}

void Builder::trace_var_indirect(int traceMaskStackID,
                                 SlotRange fixedRange,
                                 int dynamicStackID,
                                 SlotRange limitRange) {
    // SlotA: fixed-range start
    // SlotB: limit-range end
    // immA: trace-mask stack ID
    // immB: number of slots
    // immC: dynamic stack ID
    fInstructions.push_back({BuilderOp::trace_var_indirect,
                             {fixedRange.index, limitRange.index + limitRange.count},
                             traceMaskStackID,
                             fixedRange.count,
                             dynamicStackID});
}

void Builder::push_constant_i(int32_t val, int count) {
    SkASSERT(count >= 0);
    if (count > 0) {
        if (!fInstructions.empty()) {
            Instruction& lastInstruction = fInstructions.back();

            // If the previous op is pushing the same value, we can just push more of them.
            if (lastInstruction.fOp == BuilderOp::push_constant && lastInstruction.fImmB == val) {
                lastInstruction.fImmA += count;
                return;
            }
        }
        fInstructions.push_back({BuilderOp::push_constant, {}, count, val});
    }
}

void Builder::push_duplicates(int count) {
    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        // If the previous op is pushing a constant, we can just push more of them.
        if (lastInstruction.fOp == BuilderOp::push_constant) {
            lastInstruction.fImmA += count;
            return;
        }
    }
    SkASSERT(count >= 0);
    if (count >= 3) {
        // Use a swizzle to splat the input into a 4-slot value.
        this->swizzle(/*consumedSlots=*/1, {0, 0, 0, 0});
        count -= 3;
    }
    for (; count >= 4; count -= 4) {
        // Clone the splatted value four slots at a time.
        this->push_clone(/*numSlots=*/4);
    }
    // Use a swizzle or clone to handle the trailing items.
    switch (count) {
        case 3:  this->swizzle(/*consumedSlots=*/1, {0, 0, 0, 0}); break;
        case 2:  this->swizzle(/*consumedSlots=*/1, {0, 0, 0});    break;
        case 1:  this->push_clone(/*numSlots=*/1);                 break;
        default: break;
    }
}

void Builder::push_clone(int numSlots, int offsetFromStackTop) {
    // If we are cloning the stack top...
    if (numSlots == 1 && offsetFromStackTop == 0) {
        if (!fInstructions.empty()) {
            // ... and the previous op is pushing a constant...
            Instruction& lastInstruction = fInstructions.back();
            if (lastInstruction.fOp == BuilderOp::push_constant) {
                // ... we can just push more of them.
                lastInstruction.fImmA += 1;
                return;
            }
        }
    }
    fInstructions.push_back({BuilderOp::push_clone, {}, numSlots, numSlots + offsetFromStackTop});
}

void Builder::push_clone_from_stack(SlotRange range, int otherStackID, int offsetFromStackTop) {
    // immA: number of slots
    // immB: other stack ID
    // immC: offset from stack top
    offsetFromStackTop -= range.index;

    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        // If the previous op is also pushing a clone...
        if (lastInstruction.fOp == BuilderOp::push_clone_from_stack &&
            // ... from the same stack...
            lastInstruction.fImmB == otherStackID &&
            // ... and this clone starts at the same place that the last clone ends...
            lastInstruction.fImmC - lastInstruction.fImmA == offsetFromStackTop) {
            // ... just extend the existing clone-op.
            lastInstruction.fImmA += range.count;
            return;
        }
    }

    fInstructions.push_back({BuilderOp::push_clone_from_stack, {},
                             range.count, otherStackID, offsetFromStackTop});
}

void Builder::push_clone_indirect_from_stack(SlotRange fixedOffset,
                                             int dynamicStackID,
                                             int otherStackID,
                                             int offsetFromStackTop) {
    // immA: number of slots
    // immB: other stack ID
    // immC: offset from stack top
    // immD: dynamic stack ID
    offsetFromStackTop -= fixedOffset.index;

    fInstructions.push_back({BuilderOp::push_clone_indirect_from_stack, {},
                             fixedOffset.count, otherStackID, offsetFromStackTop, dynamicStackID});
}

void Builder::pop_slots(SlotRange dst) {
    if (!this->executionMaskWritesAreEnabled()) {
        this->pop_slots_unmasked(dst);
        return;
    }

    this->copy_stack_to_slots(dst);
    this->discard_stack(dst.count);
}

void Builder::simplifyPopSlotsUnmasked(SlotRange* dst) {
    if (!dst->count || fInstructions.empty()) {
        // There's nothing left to simplify.
        return;
    }

    Instruction& lastInstruction = fInstructions.back();

    // If the last instruction is pushing a constant, we can simplify it by copying the constant
    // directly into the destination slot.
    if (lastInstruction.fOp == BuilderOp::push_constant) {
        // Get the last slot.
        int32_t value = lastInstruction.fImmB;
        lastInstruction.fImmA--;
        if (lastInstruction.fImmA == 0) {
            fInstructions.pop_back();
        }

        // Consume one destination slot.
        dst->count--;
        Slot destinationSlot = dst->index + dst->count;

        // Continue simplifying if possible.
        this->simplifyPopSlotsUnmasked(dst);

        // Write the constant directly to the destination slot.
        this->copy_constant(destinationSlot, value);
        return;
    }

    // If the last instruction is pushing a uniform, we can simplify it by copying the uniform
    // directly into the destination slot.
    if (lastInstruction.fOp == BuilderOp::push_uniform) {
        // Get the last slot.
        Slot sourceSlot = lastInstruction.fSlotA + lastInstruction.fImmA - 1;
        lastInstruction.fImmA--;
        if (lastInstruction.fImmA == 0) {
            fInstructions.pop_back();
        }

        // Consume one destination slot.
        dst->count--;
        Slot destinationSlot = dst->index + dst->count;

        // Continue simplifying if possible.
        this->simplifyPopSlotsUnmasked(dst);

        // Write the constant directly to the destination slot.
        this->copy_uniform_to_slots_unmasked({destinationSlot, 1}, {sourceSlot, 1});
        return;
    }

    // If the last instruction is pushing a slot, we can just copy that slot.
    if (lastInstruction.fOp == BuilderOp::push_slots) {
        // Get the last slot.
        Slot sourceSlot = lastInstruction.fSlotA + lastInstruction.fImmA - 1;
        lastInstruction.fImmA--;
        if (lastInstruction.fImmA == 0) {
            fInstructions.pop_back();
        }

        // Consume one destination slot.
        dst->count--;
        Slot destinationSlot = dst->index + dst->count;

        // Try once more.
        this->simplifyPopSlotsUnmasked(dst);

        // Copy the slot directly.
        if (destinationSlot != sourceSlot) {
            this->copy_slots_unmasked({destinationSlot, 1}, {sourceSlot, 1});
        }
        return;
    }
}

void Builder::pop_slots_unmasked(SlotRange dst) {
    SkASSERT(dst.count >= 0);
    this->copy_stack_to_slots_unmasked(dst);
    this->discard_stack(dst.count);
}

void Builder::exchange_src() {
    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        // If the previous op is also an exchange-src...
        if (lastInstruction.fOp == BuilderOp::exchange_src) {
            // ... both ops can be eliminated. A double-swap is a no-op.
            fInstructions.pop_back();
            return;
        }
    }

    fInstructions.push_back({BuilderOp::exchange_src, {}});
}

void Builder::pop_src_rgba() {
    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        // If the previous op is exchanging src.rgba with the stack...
        if (lastInstruction.fOp == BuilderOp::exchange_src) {
            // ... both ops can be eliminated. It's just sliding the color back and forth.
            fInstructions.pop_back();
            this->discard_stack(4);
            return;
        }
    }

    fInstructions.push_back({BuilderOp::pop_src_rgba, {}});
}

void Builder::copy_stack_to_slots(SlotRange dst, int offsetFromStackTop) {
    // If the execution mask is known to be all-true, then we can ignore the write mask.
    if (!this->executionMaskWritesAreEnabled()) {
        this->copy_stack_to_slots_unmasked(dst, offsetFromStackTop);
        return;
    }

    // If the last instruction copied the previous stack slots, just extend it.
    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        // If the last op is copy-stack-to-slots...
        if (lastInstruction.fOp == BuilderOp::copy_stack_to_slots &&
            // and this op's destination is immediately after the last copy-slots-op's destination
            lastInstruction.fSlotA + lastInstruction.fImmA == dst.index &&
            // and this op's source is immediately after the last copy-slots-op's source
            lastInstruction.fImmB - lastInstruction.fImmA == offsetFromStackTop) {
            // then we can just extend the copy!
            lastInstruction.fImmA += dst.count;
            return;
        }
    }

    fInstructions.push_back({BuilderOp::copy_stack_to_slots, {dst.index},
                             dst.count, offsetFromStackTop});
}

void Builder::copy_stack_to_slots_indirect(SlotRange fixedRange,
                                           int dynamicStackID,
                                           SlotRange limitRange) {
    // SlotA: fixed-range start
    // SlotB: limit-range end
    // immA: number of slots
    // immB: dynamic stack ID
    fInstructions.push_back({BuilderOp::copy_stack_to_slots_indirect,
                             {fixedRange.index, limitRange.index + limitRange.count},
                             fixedRange.count,
                             dynamicStackID});
}

static bool slot_ranges_overlap(SlotRange x, SlotRange y) {
    return x.index < y.index + y.count &&
           y.index < x.index + x.count;
}

void Builder::copy_constant(Slot slot, int constantValue) {
    // If the last instruction copied the same constant, just extend it.
    if (!fInstructions.empty()) {
        Instruction& lastInstr = fInstructions.back();

        // If the last op is copy-constant...
        if (lastInstr.fOp == BuilderOp::copy_constant &&
            // ... and has the same value...
            lastInstr.fImmB == constantValue &&
            // ... and the slot is immediately after the last copy-constant's destination...
            lastInstr.fSlotA + lastInstr.fImmA == slot) {
            // ... then we can extend the copy!
            lastInstr.fImmA += 1;
            return;
        }
    }

    fInstructions.push_back({BuilderOp::copy_constant, {slot}, 1, constantValue});
}

void Builder::copy_slots_unmasked(SlotRange dst, SlotRange src) {
    // If the last instruction copied adjacent slots, just extend it.
    if (!fInstructions.empty()) {
        Instruction& lastInstr = fInstructions.back();

        // If the last op is copy-slots-unmasked...
        if (lastInstr.fOp == BuilderOp::copy_slot_unmasked &&
            // and this op's destination is immediately after the last copy-slots-op's destination
            lastInstr.fSlotA + lastInstr.fImmA == dst.index &&
            // and this op's source is immediately after the last copy-slots-op's source
            lastInstr.fSlotB + lastInstr.fImmA == src.index &&
            // and the source/dest ranges will not overlap
            !slot_ranges_overlap({lastInstr.fSlotB, lastInstr.fImmA + dst.count},
                                 {lastInstr.fSlotA, lastInstr.fImmA + dst.count})) {
            // then we can just extend the copy!
            lastInstr.fImmA += dst.count;
            return;
        }
    }

    SkASSERT(dst.count == src.count);
    fInstructions.push_back({BuilderOp::copy_slot_unmasked, {dst.index, src.index}, dst.count});
}

void Builder::copy_uniform_to_slots_unmasked(SlotRange dst, SlotRange src) {
    // If the last instruction copied adjacent slots, just extend it.
    if (!fInstructions.empty()) {
        Instruction& lastInstr = fInstructions.back();

        // If the last op is copy-constant...
        if (lastInstr.fOp == BuilderOp::copy_uniform_to_slots_unmasked &&
            // and this op's destination is immediately after the last copy-constant's destination
            lastInstr.fSlotB + lastInstr.fImmA == dst.index &&
            // and this op's source is immediately after the last copy-constant's source
            lastInstr.fSlotA + lastInstr.fImmA == src.index) {
            // then we can just extend the copy!
            lastInstr.fImmA += dst.count;
            return;
        }
    }

    SkASSERT(dst.count == src.count);
    fInstructions.push_back({BuilderOp::copy_uniform_to_slots_unmasked, {src.index, dst.index},
                             dst.count});
}

void Builder::copy_stack_to_slots_unmasked(SlotRange dst, int offsetFromStackTop) {
    // If the last instruction copied the previous stack slots, just extend it.
    if (!fInstructions.empty()) {
        Instruction& lastInstr = fInstructions.back();

        // If the last op is copy-stack-to-slots-unmasked...
        if (lastInstr.fOp == BuilderOp::copy_stack_to_slots_unmasked &&
            // and this op's destination is immediately after the last copy-slots-op's destination
            lastInstr.fSlotA + lastInstr.fImmA == dst.index &&
            // and this op's source is immediately after the last copy-slots-op's source
            lastInstr.fImmB - lastInstr.fImmA == offsetFromStackTop) {
            // then we can just extend the copy!
            lastInstr.fImmA += dst.count;
            return;
        }
    }

    fInstructions.push_back({BuilderOp::copy_stack_to_slots_unmasked, {dst.index},
                             dst.count, offsetFromStackTop});
}

void Builder::pop_return_mask() {
    SkASSERT(this->executionMaskWritesAreEnabled());

    // This instruction is going to overwrite the return mask. If the previous instruction was
    // masking off the return mask, that's wasted work and it can be eliminated.
    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        if (lastInstruction.fOp == BuilderOp::mask_off_return_mask) {
            fInstructions.pop_back();
        }
    }

    fInstructions.push_back({BuilderOp::pop_return_mask, {}});
}

void Builder::zero_slots_unmasked(SlotRange dst) {
    if (!fInstructions.empty()) {
        Instruction& lastInstruction = fInstructions.back();

        if (lastInstruction.fOp == BuilderOp::copy_constant && lastInstruction.fImmB == 0) {
            if (lastInstruction.fSlotA + lastInstruction.fImmA == dst.index) {
                // The previous instruction was zeroing the range immediately before this range.
                // Combine the ranges.
                lastInstruction.fImmA += dst.count;
                return;
            }

            if (lastInstruction.fSlotA == dst.index + dst.count) {
                // The previous instruction was zeroing the range immediately after this range.
                // Combine the ranges.
                lastInstruction.fSlotA = dst.index;
                lastInstruction.fImmA += dst.count;
                return;
            }
        }
    }

    fInstructions.push_back({BuilderOp::copy_constant, {dst.index}, dst.count, 0});
}

static int pack_nybbles(SkSpan<const int8_t> components) {
    // Pack up to 8 elements into nybbles, in reverse order.
    int packed = 0;
    for (auto iter = components.rbegin(); iter != components.rend(); ++iter) {
        SkASSERT(*iter >= 0 && *iter <= 0xF);
        packed <<= 4;
        packed |= *iter;
    }
    return packed;
}

template <typename T>
static void unpack_nybbles_to_offsets(uint32_t components, SkSpan<T> offsets) {
    // Unpack component nybbles into byte-offsets pointing at stack slots.
    for (size_t index = 0; index < offsets.size(); ++index) {
        offsets[index] = (components & 0xF) * SkOpts::raster_pipeline_highp_stride * sizeof(float);
        components >>= 4;
    }
}

static int max_packed_nybble(uint32_t components, size_t numComponents) {
    int largest = 0;
    for (size_t index = 0; index < numComponents; ++index) {
        largest = std::max<int>(largest, components & 0xF);
        components >>= 4;
    }
    return largest;
}

void Builder::swizzle_copy_stack_to_slots(SlotRange dst,
                                          SkSpan<const int8_t> components,
                                          int offsetFromStackTop) {
    // When the execution-mask writes-enabled flag is off, we could squeeze out a little bit of
    // extra speed here by implementing and using an unmasked version of this op.

    // SlotA: fixed-range start
    // immA: number of swizzle components
    // immB: swizzle components
    // immC: offset from stack top
    fInstructions.push_back({BuilderOp::swizzle_copy_stack_to_slots, {dst.index},
                             (int)components.size(),
                             pack_nybbles(components),
                             offsetFromStackTop});
}

void Builder::swizzle_copy_stack_to_slots_indirect(SlotRange fixedRange,
                                                   int dynamicStackID,
                                                   SlotRange limitRange,
                                                   SkSpan<const int8_t> components,
                                                   int offsetFromStackTop) {
    // When the execution-mask writes-enabled flag is off, we could squeeze out a little bit of
    // extra speed here by implementing and using an unmasked version of this op.

    // SlotA: fixed-range start
    // SlotB: limit-range end
    // immA: number of swizzle components
    // immB: swizzle components
    // immC: offset from stack top
    // immD: dynamic stack ID
    fInstructions.push_back({BuilderOp::swizzle_copy_stack_to_slots_indirect,
                             {fixedRange.index, limitRange.index + limitRange.count},
                             (int)components.size(),
                             pack_nybbles(components),
                             offsetFromStackTop,
                             dynamicStackID});
}

void Builder::swizzle(int consumedSlots, SkSpan<const int8_t> components) {
    // Consumes `consumedSlots` elements on the stack, then generates `elementSpan.size()` elements.
    SkASSERT(consumedSlots >= 0);

    // We only allow up to 16 elements, and they can only reach 0-15 slots, due to nybble packing.
    int numElements = components.size();
    SkASSERT(numElements <= 16);
    SkASSERT(std::all_of(components.begin(), components.end(), [](int8_t e){ return e >= 0; }));
    SkASSERT(std::all_of(components.begin(), components.end(), [](int8_t e){ return e <= 0xF; }));

    // Make a local copy of the element array.
    int8_t elements[16] = {};
    std::copy(components.begin(), components.end(), std::begin(elements));

    while (numElements > 0) {
        // If the first element of the swizzle is zero...
        if (elements[0] != 0) {
            break;
        }
        // ...and zero isn't used elsewhere in the swizzle...
        if (std::any_of(&elements[1], &elements[numElements], [](int8_t e) { return e == 0; })) {
            break;
        }
        // We can omit the first slot from the swizzle entirely.
        // Slide everything forward by one slot, and reduce the element index by one.
        for (int index = 1; index < numElements; ++index) {
            elements[index - 1] = elements[index] - 1;
        }
        elements[numElements - 1] = 0;
        --consumedSlots;
        --numElements;
    }

    // A completely empty swizzle is a no-op.
    if (numElements == 0) {
        this->discard_stack(consumedSlots);
        return;
    }

    if (consumedSlots <= 4 && numElements <= 4) {
        // We can fit everything into a little swizzle.
        int op = (int)BuilderOp::swizzle_1 + numElements - 1;
        fInstructions.push_back({(BuilderOp)op, {}, consumedSlots,
                                 pack_nybbles(SkSpan(elements, numElements))});
        return;
    }

    // This is a big swizzle. We use the `shuffle` op to handle these. immA counts the consumed
    // slots. immB counts the generated slots. immC and immD hold packed-nybble shuffle values.
    fInstructions.push_back({BuilderOp::shuffle, {},
                             consumedSlots, numElements,
                             pack_nybbles(SkSpan(&elements[0], 8)),
                             pack_nybbles(SkSpan(&elements[8], 8))});
}

void Builder::transpose(int columns, int rows) {
    // Transposes a matrix of size CxR on the stack (into a matrix of size RxC).
    int8_t elements[16] = {};
    size_t index = 0;
    for (int r = 0; r < rows; ++r) {
        for (int c = 0; c < columns; ++c) {
            elements[index++] = (c * rows) + r;
        }
    }
    this->swizzle(/*consumedSlots=*/columns * rows, SkSpan(elements, index));
}

void Builder::diagonal_matrix(int columns, int rows) {
    // Generates a CxR diagonal matrix from the top two scalars on the stack.
    int8_t elements[16] = {};
    size_t index = 0;
    for (int c = 0; c < columns; ++c) {
        for (int r = 0; r < rows; ++r) {
            elements[index++] = (c == r) ? 1 : 0;
        }
    }
    this->swizzle(/*consumedSlots=*/2, SkSpan(elements, index));
}

void Builder::matrix_resize(int origColumns, int origRows, int newColumns, int newRows) {
    // Resizes a CxR matrix at the top of the stack to C'xR'.
    int8_t elements[16] = {};
    size_t index = 0;

    size_t consumedSlots = origColumns * origRows;
    size_t zeroOffset = 0, oneOffset = 0;

    for (int c = 0; c < newColumns; ++c) {
        for (int r = 0; r < newRows; ++r) {
            if (c < origColumns && r < origRows) {
                // Push an element from the original matrix.
                elements[index++] = (c * origRows) + r;
            } else {
                // This element is outside the original matrix; push 1 or 0.
                if (c == r) {
                    // We need to synthesize a literal 1.
                    if (oneOffset == 0) {
                        this->push_constant_f(1.0f);
                        oneOffset = consumedSlots++;
                    }
                    elements[index++] = oneOffset;
                } else {
                    // We need to synthesize a literal 0.
                    if (zeroOffset == 0) {
                        this->push_constant_f(0.0f);
                        zeroOffset = consumedSlots++;
                    }
                    elements[index++] = zeroOffset;
                }
            }
        }
    }
    this->swizzle(consumedSlots, SkSpan(elements, index));
}

void Builder::matrix_multiply(int leftColumns, int leftRows, int rightColumns, int rightRows) {
    BuilderOp op;
    switch (leftColumns) {
        case 2:  op = BuilderOp::matrix_multiply_2; break;
        case 3:  op = BuilderOp::matrix_multiply_3; break;
        case 4:  op = BuilderOp::matrix_multiply_4; break;
        default: SkDEBUGFAIL("unsupported matrix dimensions"); return;
    }

    fInstructions.push_back({op, {}, leftColumns, leftRows, rightColumns, rightRows});
}

std::unique_ptr<Program> Builder::finish(int numValueSlots,
                                         int numUniformSlots,
                                         DebugTracePriv* debugTrace) {
    // Verify that calls to enableExecutionMaskWrites and disableExecutionMaskWrites are balanced.
    SkASSERT(fExecutionMaskWritesEnabled == 0);

    return std::make_unique<Program>(std::move(fInstructions), numValueSlots, numUniformSlots,
                                     fNumLabels, debugTrace);
}

void Program::optimize() {
    // TODO(johnstiles): perform any last-minute cleanup of the instruction stream here
}

static int stack_usage(const Instruction& inst) {
    switch (inst.fOp) {
        case BuilderOp::push_condition_mask:
        case BuilderOp::push_loop_mask:
        case BuilderOp::push_return_mask:
            return 1;

        case BuilderOp::push_src_rgba:
        case BuilderOp::push_dst_rgba:
        case BuilderOp::push_device_xy01:
            return 4;

        case BuilderOp::push_constant:
        case BuilderOp::push_slots:
        case BuilderOp::push_slots_indirect:
        case BuilderOp::push_uniform:
        case BuilderOp::push_uniform_indirect:
        case BuilderOp::push_clone:
        case BuilderOp::push_clone_from_stack:
        case BuilderOp::push_clone_indirect_from_stack:
        case BuilderOp::pad_stack:
            return inst.fImmA;

        case BuilderOp::pop_condition_mask:
        case BuilderOp::pop_loop_mask:
        case BuilderOp::pop_and_reenable_loop_mask:
        case BuilderOp::pop_return_mask:
            return -1;

        case BuilderOp::pop_src_rgba:
        case BuilderOp::pop_dst_rgba:
            return -4;

        case ALL_N_WAY_BINARY_OP_CASES:
        case ALL_MULTI_SLOT_BINARY_OP_CASES:
        case BuilderOp::discard_stack:
        case BuilderOp::select:
            return -inst.fImmA;

        case ALL_N_WAY_TERNARY_OP_CASES:
        case ALL_MULTI_SLOT_TERNARY_OP_CASES:
            return 2 * -inst.fImmA;

        case BuilderOp::swizzle_1:
            return 1 - inst.fImmA;  // consumes immA slots and emits a scalar
        case BuilderOp::swizzle_2:
            return 2 - inst.fImmA;  // consumes immA slots and emits a 2-slot vector
        case BuilderOp::swizzle_3:
            return 3 - inst.fImmA;  // consumes immA slots and emits a 3-slot vector
        case BuilderOp::swizzle_4:
            return 4 - inst.fImmA;  // consumes immA slots and emits a 4-slot vector

        case BuilderOp::dot_2_floats:
            return -3;  // consumes two 2-slot vectors and emits one scalar
        case BuilderOp::dot_3_floats:
            return -5;  // consumes two 3-slot vectors and emits one scalar
        case BuilderOp::dot_4_floats:
            return -7;  // consumes two 4-slot vectors and emits one scalar

        case BuilderOp::refract_4_floats:
            return -5;  // consumes nine slots (N + I + eta) and emits a 4-slot vector (R)

        case BuilderOp::matrix_multiply_2:
        case BuilderOp::matrix_multiply_3:
        case BuilderOp::matrix_multiply_4:
            // consumes the left- and right-matrices; emits result over existing padding slots
            return -(inst.fImmA * inst.fImmB + inst.fImmC * inst.fImmD);

        case BuilderOp::shuffle: {
            int consumed = inst.fImmA;
            int generated = inst.fImmB;
            return generated - consumed;
        }
        case ALL_SINGLE_SLOT_UNARY_OP_CASES:
        case ALL_MULTI_SLOT_UNARY_OP_CASES:
        case ALL_IMMEDIATE_BINARY_OP_CASES:
        default:
            return 0;
    }
}

Program::StackDepths Program::tempStackMaxDepths() const {
    // Count the number of separate temp stacks that the program uses.
    int numStacks = 1;
    for (const Instruction& inst : fInstructions) {
        if (inst.fOp == BuilderOp::set_current_stack) {
            numStacks = std::max(numStacks, inst.fImmA + 1);
        }
    }

    // Walk the program and calculate how deep each stack can potentially get.
    StackDepths largest, current;
    largest.push_back_n(numStacks, 0);
    current.push_back_n(numStacks, 0);

    int curIdx = 0;
    for (const Instruction& inst : fInstructions) {
        if (inst.fOp == BuilderOp::set_current_stack) {
            curIdx = inst.fImmA;
            SkASSERTF(curIdx >= 0 && curIdx < numStacks,
                      "instruction references nonexistent stack %d", curIdx);
        }
        current[curIdx] += stack_usage(inst);
        largest[curIdx] = std::max(current[curIdx], largest[curIdx]);
        // If we assert here, the generated program has popped off the top of the stack.
        SkASSERTF(current[curIdx] >= 0, "unbalanced temp stack push/pop on stack %d", curIdx);
    }

    // Ensure that when the program is complete, our stacks are fully balanced.
    for (int stackIdx = 0; stackIdx < numStacks; ++stackIdx) {
        // If we assert here, the generated program has pushed more data than it has popped.
        SkASSERTF(current[stackIdx] == 0, "unbalanced temp stack push/pop on stack %d", stackIdx);
    }

    return largest;
}

Program::Program(TArray<Instruction> instrs,
                 int numValueSlots,
                 int numUniformSlots,
                 int numLabels,
                 DebugTracePriv* debugTrace)
        : fInstructions(std::move(instrs))
        , fNumValueSlots(numValueSlots)
        , fNumUniformSlots(numUniformSlots)
        , fNumLabels(numLabels)
        , fDebugTrace(debugTrace) {
    this->optimize();

    fTempStackMaxDepths = this->tempStackMaxDepths();

    fNumTempStackSlots = 0;
    for (const int depth : fTempStackMaxDepths) {
        fNumTempStackSlots += depth;
    }

    if (fDebugTrace) {
        fTraceHook = SkSL::Tracer::Make(&fDebugTrace->fTraceInfo);
    }
}

Program::~Program() = default;

void Program::appendCopy(TArray<Stage>* pipeline,
                         SkArenaAlloc* alloc,
                         ProgramOp baseStage,
                         SkRPOffset dst,
                         SkRPOffset src,
                         int numSlots) const {
    SkASSERT(numSlots >= 0);
    while (numSlots > 4) {
        this->appendCopy(pipeline, alloc, baseStage, dst, src, /*numSlots=*/4);
        dst += 4 * SkOpts::raster_pipeline_highp_stride * sizeof(float);
        src += 4 * SkOpts::raster_pipeline_highp_stride * sizeof(float);
        numSlots -= 4;
    }

    if (numSlots > 0) {
        SkASSERT(numSlots <= 4);
        auto stage = (ProgramOp)((int)baseStage + numSlots - 1);
        SkRasterPipeline_BinaryOpCtx ctx;
        ctx.dst = dst;
        ctx.src = src;
        pipeline->push_back({stage, SkRPCtxUtils::Pack(ctx, alloc)});
    }
}

void Program::appendCopySlotsUnmasked(TArray<Stage>* pipeline,
                                      SkArenaAlloc* alloc,
                                      SkRPOffset dst,
                                      SkRPOffset src,
                                      int numSlots) const {
    this->appendCopy(pipeline, alloc,
                     ProgramOp::copy_slot_unmasked,
                     dst,  src, numSlots);
}

void Program::appendCopySlotsMasked(TArray<Stage>* pipeline,
                                    SkArenaAlloc* alloc,
                                    SkRPOffset dst,
                                    SkRPOffset src,
                                    int numSlots) const {
    this->appendCopy(pipeline, alloc,
                     ProgramOp::copy_slot_masked,
                     dst, src, numSlots);
}

void Program::appendSingleSlotUnaryOp(TArray<Stage>* pipeline, ProgramOp stage,
                                      float* dst, int numSlots) const {
    SkASSERT(numSlots >= 0);
    while (numSlots--) {
        pipeline->push_back({stage, dst});
        dst += SkOpts::raster_pipeline_highp_stride;
    }
}

void Program::appendMultiSlotUnaryOp(TArray<Stage>* pipeline, ProgramOp baseStage,
                                     float* dst, int numSlots) const {
    SkASSERT(numSlots >= 0);
    while (numSlots > 0) {
        int currentSlots = std::min(numSlots, 4);
        auto stage = (ProgramOp)((int)baseStage + currentSlots - 1);
        pipeline->push_back({stage, dst});

        dst += 4 * SkOpts::raster_pipeline_highp_stride;
        numSlots -= 4;
    }
}

void Program::appendImmediateBinaryOp(TArray<Stage>* pipeline, SkArenaAlloc* alloc,
                                      ProgramOp baseStage,
                                      SkRPOffset dst, float value, int numSlots) const {
    SkASSERT(is_immediate_op((BuilderOp)baseStage));
    SkASSERT(numSlots == 1 || is_multi_slot_immediate_op((BuilderOp)baseStage));

    SkRasterPipeline_ConstantCtx ctx;
    ctx.dst = dst;
    ctx.value = value;

    SkASSERT(numSlots >= 0);
    while (numSlots > 0) {
        int currentSlots = std::min(numSlots, 4);
        auto stage = (ProgramOp)((int)baseStage - (currentSlots - 1));
        pipeline->push_back({stage, SkRPCtxUtils::Pack(ctx, alloc)});

        ctx.dst += 4 * SkOpts::raster_pipeline_highp_stride * sizeof(float);
        numSlots -= 4;
    }
}

void Program::appendAdjacentNWayBinaryOp(TArray<Stage>* pipeline, SkArenaAlloc* alloc,
                                         ProgramOp stage,
                                         SkRPOffset dst, SkRPOffset src, int numSlots) const {
    // The source and destination must be directly next to one another.
    SkASSERT(numSlots >= 0);
    SkASSERT((dst + SkOpts::raster_pipeline_highp_stride * numSlots * sizeof(float)) == src);

    if (numSlots > 0) {
        SkRasterPipeline_BinaryOpCtx ctx;
        ctx.dst = dst;
        ctx.src = src;
        pipeline->push_back({stage, SkRPCtxUtils::Pack(ctx, alloc)});
    }
}

void Program::appendAdjacentMultiSlotBinaryOp(TArray<Stage>* pipeline, SkArenaAlloc* alloc,
                                              ProgramOp baseStage, std::byte* basePtr,
                                              SkRPOffset dst, SkRPOffset src, int numSlots) const {
    // The source and destination must be directly next to one another.
    SkASSERT(numSlots >= 0);
    SkASSERT((dst + SkOpts::raster_pipeline_highp_stride * numSlots * sizeof(float)) == src);

    if (numSlots > 4) {
        this->appendAdjacentNWayBinaryOp(pipeline, alloc, baseStage, dst, src, numSlots);
        return;
    }
    if (numSlots > 0) {
        auto specializedStage = (ProgramOp)((int)baseStage + numSlots);
        pipeline->push_back({specializedStage, basePtr + dst});
    }
}

void Program::appendAdjacentNWayTernaryOp(TArray<Stage>* pipeline, SkArenaAlloc* alloc,
                                          ProgramOp stage, std::byte* basePtr, SkRPOffset dst,
                                          SkRPOffset src0, SkRPOffset src1, int numSlots) const {
    // The float pointers must all be immediately adjacent to each other.
    SkASSERT(numSlots >= 0);
    SkASSERT((dst  + SkOpts::raster_pipeline_highp_stride * numSlots * sizeof(float)) == src0);
    SkASSERT((src0 + SkOpts::raster_pipeline_highp_stride * numSlots * sizeof(float)) == src1);

    if (numSlots > 0) {
        SkRasterPipeline_TernaryOpCtx ctx;
        ctx.dst = dst;
        ctx.delta = src0 - dst;
        pipeline->push_back({stage, SkRPCtxUtils::Pack(ctx, alloc)});
    }
}

void Program::appendAdjacentMultiSlotTernaryOp(TArray<Stage>* pipeline, SkArenaAlloc* alloc,
                                               ProgramOp baseStage, std::byte* basePtr,
                                               SkRPOffset dst, SkRPOffset src0, SkRPOffset src1,
                                               int numSlots) const {
    // The float pointers must all be immediately adjacent to each other.
    SkASSERT(numSlots >= 0);
    SkASSERT((dst  + SkOpts::raster_pipeline_highp_stride * numSlots * sizeof(float)) == src0);
    SkASSERT((src0 + SkOpts::raster_pipeline_highp_stride * numSlots * sizeof(float)) == src1);

    if (numSlots > 4) {
        this->appendAdjacentNWayTernaryOp(pipeline, alloc, baseStage, basePtr,
                                          dst, src0, src1, numSlots);
        return;
    }
    if (numSlots > 0) {
        auto specializedStage = (ProgramOp)((int)baseStage + numSlots);
        pipeline->push_back({specializedStage, basePtr + dst});
    }
}

void Program::appendStackRewind(TArray<Stage>* pipeline) const {
#if defined(SKSL_STANDALONE) || !SK_HAS_MUSTTAIL
    pipeline->push_back({ProgramOp::stack_rewind, nullptr});
#endif
}

static void* context_bit_pun(intptr_t val) {
    return sk_bit_cast<void*>(val);
}

Program::SlotData Program::allocateSlotData(SkArenaAlloc* alloc) const {
    // Allocate a contiguous slab of slot data for values and stack entries.
    const int N = SkOpts::raster_pipeline_highp_stride;
    const int vectorWidth = N * sizeof(float);
    const int allocSize = vectorWidth * (fNumValueSlots + fNumTempStackSlots);
    float* slotPtr = static_cast<float*>(alloc->makeBytesAlignedTo(allocSize, vectorWidth));
    sk_bzero(slotPtr, allocSize);

    // Store the temp stack immediately after the values.
    SlotData s;
    s.values = SkSpan{slotPtr,        N * fNumValueSlots};
    s.stack  = SkSpan{s.values.end(), N * fNumTempStackSlots};
    return s;
}

bool Program::appendStages(SkRasterPipeline* pipeline,
                           SkArenaAlloc* alloc,
                           RP::Callbacks* callbacks,
                           SkSpan<const float> uniforms) const {
#if defined(SKSL_STANDALONE)
    return false;
#else
    // Convert our Instruction list to an array of ProgramOps.
    TArray<Stage> stages;
    SlotData slotData = this->allocateSlotData(alloc);
    this->makeStages(&stages, alloc, uniforms, slotData);

    // Allocate buffers for branch targets and labels; these are needed to convert labels into
    // actual offsets into the pipeline and fix up branches.
    TArray<SkRasterPipeline_BranchCtx*> branchContexts;
    branchContexts.reserve_exact(fNumLabels);
    TArray<int> labelOffsets;
    labelOffsets.push_back_n(fNumLabels, -1);
    TArray<int> branchGoesToLabel;
    branchGoesToLabel.reserve_exact(fNumLabels);

    auto resetBasePointer = [&]() {
        // Whenever we hand off control to another shader, we have to assume that it might overwrite
        // the base pointer (if it uses SkSL, it will!), so we reset it on return.
        pipeline->append(SkRasterPipelineOp::set_base_pointer, slotData.values.data());
    };

    resetBasePointer();

    for (const Stage& stage : stages) {
        switch (stage.op) {
            case ProgramOp::stack_rewind:
                pipeline->append_stack_rewind();
                break;

            case ProgramOp::invoke_shader:
                if (!callbacks || !callbacks->appendShader(sk_bit_cast<intptr_t>(stage.ctx))) {
                    return false;
                }
                resetBasePointer();
                break;

            case ProgramOp::invoke_color_filter:
                if (!callbacks || !callbacks->appendColorFilter(sk_bit_cast<intptr_t>(stage.ctx))) {
                    return false;
                }
                resetBasePointer();
                break;

            case ProgramOp::invoke_blender:
                if (!callbacks || !callbacks->appendBlender(sk_bit_cast<intptr_t>(stage.ctx))) {
                    return false;
                }
                resetBasePointer();
                break;

            case ProgramOp::invoke_to_linear_srgb:
                if (!callbacks) {
                    return false;
                }
                callbacks->toLinearSrgb(stage.ctx);
                // A ColorSpaceXform shouldn't ever alter the base pointer, so we don't need to call
                // resetBasePointer here.
                break;

            case ProgramOp::invoke_from_linear_srgb:
                if (!callbacks) {
                    return false;
                }
                callbacks->fromLinearSrgb(stage.ctx);
                // A ColorSpaceXform shouldn't ever alter the base pointer, so we don't need to call
                // resetBasePointer here.
                break;

            case ProgramOp::label: {
                // Remember the absolute pipeline position of this label.
                int labelID = sk_bit_cast<intptr_t>(stage.ctx);
                SkASSERT(labelID >= 0 && labelID < fNumLabels);
                labelOffsets[labelID] = pipeline->getNumStages();
                break;
            }
            case ProgramOp::jump:
            case ProgramOp::branch_if_all_lanes_active:
            case ProgramOp::branch_if_any_lanes_active:
            case ProgramOp::branch_if_no_lanes_active:
            case ProgramOp::branch_if_no_active_lanes_eq: {
                // The branch context contain a valid label ID at this point.
                auto* branchCtx = static_cast<SkRasterPipeline_BranchCtx*>(stage.ctx);
                int labelID = branchCtx->offset;
                SkASSERT(labelID >= 0 && labelID < fNumLabels);

                // Replace the label ID in the branch context with the absolute pipeline position.
                // We will go back over the branch targets at the end and fix them up.
                branchCtx->offset = pipeline->getNumStages();

                SkASSERT(branchContexts.size() == branchGoesToLabel.size());
                branchContexts.push_back(branchCtx);
                branchGoesToLabel.push_back(labelID);
                [[fallthrough]];
            }
            default:
                // Append a regular op to the program.
                SkASSERT((int)stage.op < kNumRasterPipelineHighpOps);
                pipeline->append((SkRasterPipelineOp)stage.op, stage.ctx);
                break;
        }
    }

    // Now that we have assembled the program and know the pipeline positions of each label and
    // branch, fix up every branch target.
    SkASSERT(branchContexts.size() == branchGoesToLabel.size());
    for (int index = 0; index < branchContexts.size(); ++index) {
        int branchFromIdx = branchContexts[index]->offset;
        int branchToIdx = labelOffsets[branchGoesToLabel[index]];
        branchContexts[index]->offset = branchToIdx - branchFromIdx;
    }

    return true;
#endif
}

void Program::makeStages(TArray<Stage>* pipeline,
                         SkArenaAlloc* alloc,
                         SkSpan<const float> uniforms,
                         const SlotData& slots) const {
    SkASSERT(fNumUniformSlots == SkToInt(uniforms.size()));

    const int N = SkOpts::raster_pipeline_highp_stride;
    int currentStack = 0;
    int mostRecentRewind = 0;

    // Assemble a map holding the current stack-top for each temporary stack. Position each temp
    // stack immediately after the previous temp stack; temp stacks are never allowed to overlap.
    int pos = 0;
    TArray<float*> tempStackMap;
    tempStackMap.resize(fTempStackMaxDepths.size());
    for (int idx = 0; idx < fTempStackMaxDepths.size(); ++idx) {
        tempStackMap[idx] = slots.stack.begin() + (pos * N);
        pos += fTempStackMaxDepths[idx];
    }

    // Track labels that we have reached in processing.
    SkBitSet labelsEncountered(fNumLabels);

    auto EmitStackRewindForBackwardsBranch = [&](int labelID) {
        // If we have already encountered the label associated with this branch, this is a
        // backwards branch. Add a stack-rewind immediately before the branch to ensure that
        // long-running loops don't use an unbounded amount of stack space.
        if (labelsEncountered.test(labelID)) {
            this->appendStackRewind(pipeline);
            mostRecentRewind = pipeline->size();
        }
    };

    auto* const basePtr = (std::byte*)slots.values.data();
    auto OffsetFromBase = [&](const void* ptr) -> SkRPOffset {
        return (SkRPOffset)((std::byte*)ptr - basePtr);
    };

    // Write each BuilderOp to the pipeline array.
    pipeline->reserve_exact(pipeline->size() + fInstructions.size());
    for (const Instruction& inst : fInstructions) {
        auto SlotA    = [&]() { return &slots.values[N * inst.fSlotA]; };
        auto SlotB    = [&]() { return &slots.values[N * inst.fSlotB]; };
        auto UniformA = [&]() { return &uniforms[inst.fSlotA]; };
        auto AllocTraceContext = [&](auto* ctx) {
            // We pass `ctx` solely for its type; the value is unused.
            using ContextType = typename std::remove_reference<decltype(*ctx)>::type;
            ctx = alloc->make<ContextType>();
            ctx->traceMask = reinterpret_cast<int*>(tempStackMap[inst.fImmA] - N);
            ctx->traceHook = fTraceHook.get();
            return ctx;
        };
        float*& tempStackPtr = tempStackMap[currentStack];

        switch (inst.fOp) {
            case BuilderOp::label:
                SkASSERT(inst.fImmA >= 0 && inst.fImmA < fNumLabels);
                labelsEncountered.set(inst.fImmA);
                pipeline->push_back({ProgramOp::label, context_bit_pun(inst.fImmA)});
                break;

            case BuilderOp::jump:
            case BuilderOp::branch_if_all_lanes_active:
            case BuilderOp::branch_if_any_lanes_active:
            case BuilderOp::branch_if_no_lanes_active: {
                SkASSERT(inst.fImmA >= 0 && inst.fImmA < fNumLabels);
                EmitStackRewindForBackwardsBranch(inst.fImmA);

                auto* ctx = alloc->make<SkRasterPipeline_BranchCtx>();
                ctx->offset = inst.fImmA;
                pipeline->push_back({(ProgramOp)inst.fOp, ctx});
                break;
            }
            case BuilderOp::branch_if_no_active_lanes_on_stack_top_equal: {
                SkASSERT(inst.fImmA >= 0 && inst.fImmA < fNumLabels);
                EmitStackRewindForBackwardsBranch(inst.fImmA);

                auto* ctx = alloc->make<SkRasterPipeline_BranchIfEqualCtx>();
                ctx->offset = inst.fImmA;
                ctx->value = inst.fImmB;
                ctx->ptr = reinterpret_cast<int*>(tempStackPtr - N);
                pipeline->push_back({ProgramOp::branch_if_no_active_lanes_eq, ctx});
                break;
            }
            case BuilderOp::init_lane_masks:
                pipeline->push_back({ProgramOp::init_lane_masks, nullptr});
                break;

            case BuilderOp::store_src_rg:
                pipeline->push_back({ProgramOp::store_src_rg, SlotA()});
                break;

            case BuilderOp::store_src:
                pipeline->push_back({ProgramOp::store_src, SlotA()});
                break;

            case BuilderOp::store_dst:
                pipeline->push_back({ProgramOp::store_dst, SlotA()});
                break;

            case BuilderOp::store_device_xy01:
                pipeline->push_back({ProgramOp::store_device_xy01, SlotA()});
                break;

            case BuilderOp::load_src:
                pipeline->push_back({ProgramOp::load_src, SlotA()});
                break;

            case BuilderOp::load_dst:
                pipeline->push_back({ProgramOp::load_dst, SlotA()});
                break;

            case ALL_SINGLE_SLOT_UNARY_OP_CASES: {
                float* dst = tempStackPtr - (inst.fImmA * N);
                this->appendSingleSlotUnaryOp(pipeline, (ProgramOp)inst.fOp, dst, inst.fImmA);
                break;
            }
            case ALL_MULTI_SLOT_UNARY_OP_CASES: {
                float* dst = tempStackPtr - (inst.fImmA * N);
                this->appendMultiSlotUnaryOp(pipeline, (ProgramOp)inst.fOp, dst, inst.fImmA);
                break;
            }
            case ALL_IMMEDIATE_BINARY_OP_CASES: {
                float* dst = (inst.fSlotA == NA) ? tempStackPtr - (inst.fImmA * N)
                                                 : SlotA();

                this->appendImmediateBinaryOp(pipeline, alloc, (ProgramOp)inst.fOp,
                                              OffsetFromBase(dst), sk_bit_cast<float>(inst.fImmB),
                                              inst.fImmA);
                break;
            }
            case ALL_N_WAY_BINARY_OP_CASES: {
                float* src = tempStackPtr - (inst.fImmA * N);
                float* dst = tempStackPtr - (inst.fImmA * 2 * N);
                this->appendAdjacentNWayBinaryOp(pipeline, alloc, (ProgramOp)inst.fOp,
                                                 OffsetFromBase(dst), OffsetFromBase(src),
                                                 inst.fImmA);
                break;
            }
            case ALL_MULTI_SLOT_BINARY_OP_CASES: {
                float* src = tempStackPtr - (inst.fImmA * N);
                float* dst = tempStackPtr - (inst.fImmA * 2 * N);
                this->appendAdjacentMultiSlotBinaryOp(pipeline, alloc, (ProgramOp)inst.fOp,
                                                      basePtr,
                                                      OffsetFromBase(dst),
                                                      OffsetFromBase(src),
                                                      inst.fImmA);
                break;
            }
            case ALL_N_WAY_TERNARY_OP_CASES: {
                float* src1 = tempStackPtr - (inst.fImmA * N);
                float* src0 = tempStackPtr - (inst.fImmA * 2 * N);
                float* dst  = tempStackPtr - (inst.fImmA * 3 * N);
                this->appendAdjacentNWayTernaryOp(pipeline, alloc, (ProgramOp)inst.fOp, basePtr,
                                                  OffsetFromBase(dst),
                                                  OffsetFromBase(src0),
                                                  OffsetFromBase(src1),
                                                  inst.fImmA);
                break;
            }
            case ALL_MULTI_SLOT_TERNARY_OP_CASES: {
                float* src1 = tempStackPtr - (inst.fImmA * N);
                float* src0 = tempStackPtr - (inst.fImmA * 2 * N);
                float* dst  = tempStackPtr - (inst.fImmA * 3 * N);
                this->appendAdjacentMultiSlotTernaryOp(pipeline, alloc,(ProgramOp)inst.fOp, basePtr,
                                                       OffsetFromBase(dst),
                                                       OffsetFromBase(src0),
                                                       OffsetFromBase(src1),
                                                       inst.fImmA);
                break;
            }
            case BuilderOp::select: {
                float* src = tempStackPtr - (inst.fImmA * N);
                float* dst = tempStackPtr - (inst.fImmA * 2 * N);
                this->appendCopySlotsMasked(pipeline, alloc,
                                            OffsetFromBase(dst),
                                            OffsetFromBase(src),
                                            inst.fImmA);
                break;
            }
            case BuilderOp::copy_slot_masked:
                this->appendCopySlotsMasked(pipeline, alloc,
                                            OffsetFromBase(SlotA()),
                                            OffsetFromBase(SlotB()),
                                            inst.fImmA);
                break;

            case BuilderOp::copy_slot_unmasked:
                this->appendCopySlotsUnmasked(pipeline, alloc,
                                              OffsetFromBase(SlotA()),
                                              OffsetFromBase(SlotB()),
                                              inst.fImmA);
                break;

            case BuilderOp::refract_4_floats: {
                float* dst = tempStackPtr - (9 * N);
                pipeline->push_back({ProgramOp::refract_4_floats, dst});
                break;
            }
            case BuilderOp::inverse_mat2:
            case BuilderOp::inverse_mat3:
            case BuilderOp::inverse_mat4: {
                float* dst = tempStackPtr - (inst.fImmA * N);
                pipeline->push_back({(ProgramOp)inst.fOp, dst});
                break;
            }
            case BuilderOp::dot_2_floats:
            case BuilderOp::dot_3_floats:
            case BuilderOp::dot_4_floats: {
                float* dst = tempStackPtr - (inst.fImmA * 2 * N);
                pipeline->push_back({(ProgramOp)inst.fOp, dst});
                break;
            }
            case BuilderOp::swizzle_1:
            case BuilderOp::swizzle_2:
            case BuilderOp::swizzle_3:
            case BuilderOp::swizzle_4: {
                SkRasterPipeline_SwizzleCtx ctx;
                ctx.dst = OffsetFromBase(tempStackPtr - (N * inst.fImmA));
                // Unpack component nybbles into byte-offsets pointing at stack slots.
                unpack_nybbles_to_offsets(inst.fImmB, SkSpan(ctx.offsets));
                pipeline->push_back({(ProgramOp)inst.fOp, SkRPCtxUtils::Pack(ctx, alloc)});
                break;
            }
            case BuilderOp::shuffle: {
                int consumed = inst.fImmA;
                int generated = inst.fImmB;

                auto* ctx = alloc->make<SkRasterPipeline_ShuffleCtx>();
                ctx->ptr = tempStackPtr - (N * consumed);
                ctx->count = generated;
                // Unpack immB and immC from nybble form into the offset array.
                unpack_nybbles_to_offsets(inst.fImmC, SkSpan(&ctx->offsets[0], 8));
                unpack_nybbles_to_offsets(inst.fImmD, SkSpan(&ctx->offsets[8], 8));
                pipeline->push_back({ProgramOp::shuffle, ctx});
                break;
            }
            case BuilderOp::matrix_multiply_2:
            case BuilderOp::matrix_multiply_3:
            case BuilderOp::matrix_multiply_4: {
                int consumed = (inst.fImmB * inst.fImmC) +  // result
                               (inst.fImmA * inst.fImmB) +  // left-matrix
                               (inst.fImmC * inst.fImmD);   // right-matrix

                SkRasterPipeline_MatrixMultiplyCtx ctx;
                ctx.dst = OffsetFromBase(tempStackPtr - (N * consumed));
                ctx.leftColumns  = inst.fImmA;
                ctx.leftRows     = inst.fImmB;
                ctx.rightColumns = inst.fImmC;
                ctx.rightRows    = inst.fImmD;
                pipeline->push_back({(ProgramOp)inst.fOp, SkRPCtxUtils::Pack(ctx, alloc)});
                break;
            }
            case BuilderOp::exchange_src: {
                float* dst = tempStackPtr - (4 * N);
                pipeline->push_back({ProgramOp::exchange_src, dst});
                break;
            }
            case BuilderOp::push_src_rgba: {
                float* dst = tempStackPtr;
                pipeline->push_back({ProgramOp::store_src, dst});
                break;
            }
            case BuilderOp::push_dst_rgba: {
                float* dst = tempStackPtr;
                pipeline->push_back({ProgramOp::store_dst, dst});
                break;
            }
            case BuilderOp::push_device_xy01: {
                float* dst = tempStackPtr;
                pipeline->push_back({ProgramOp::store_device_xy01, dst});
                break;
            }
            case BuilderOp::pop_src_rgba: {
                float* src = tempStackPtr - (4 * N);
                pipeline->push_back({ProgramOp::load_src, src});
                break;
            }
            case BuilderOp::pop_dst_rgba: {
                float* src = tempStackPtr - (4 * N);
                pipeline->push_back({ProgramOp::load_dst, src});
                break;
            }
            case BuilderOp::push_slots: {
                float* dst = tempStackPtr;
                this->appendCopySlotsUnmasked(pipeline, alloc,
                                              OffsetFromBase(dst),
                                              OffsetFromBase(SlotA()),
                                              inst.fImmA);
                break;
            }
            case BuilderOp::copy_stack_to_slots_indirect:
            case BuilderOp::push_slots_indirect:
            case BuilderOp::push_uniform_indirect: {
                // SlotA: fixed-range start
                // SlotB: limit-range end
                //  immA: number of slots to copy
                //  immB: dynamic stack ID
                ProgramOp op;
                auto* ctx = alloc->make<SkRasterPipeline_CopyIndirectCtx>();
                ctx->indirectOffset =
                        reinterpret_cast<const uint32_t*>(tempStackMap[inst.fImmB]) - (1 * N);
                ctx->indirectLimit = inst.fSlotB - inst.fSlotA - inst.fImmA;
                ctx->slots = inst.fImmA;
                if (inst.fOp == BuilderOp::push_slots_indirect) {
                    op = ProgramOp::copy_from_indirect_unmasked;
                    ctx->src = SlotA();
                    ctx->dst = tempStackPtr;
                } else if (inst.fOp == BuilderOp::push_uniform_indirect) {
                    op = ProgramOp::copy_from_indirect_uniform_unmasked;
                    ctx->src = UniformA();
                    ctx->dst = tempStackPtr;
                } else {
                    op = ProgramOp::copy_to_indirect_masked;
                    ctx->src = tempStackPtr - (ctx->slots * N);
                    ctx->dst = SlotA();
                }
                pipeline->push_back({op, ctx});
                break;
            }
            case BuilderOp::push_uniform:
            case BuilderOp::copy_uniform_to_slots_unmasked: {
                const float* src = UniformA();
                float* dst = (inst.fOp == BuilderOp::push_uniform) ? tempStackPtr : SlotB();

                for (int remaining = inst.fImmA; remaining > 0; remaining -= 4) {
                    auto ctx = alloc->make<SkRasterPipeline_UniformCtx>();
                    ctx->dst = dst;
                    ctx->src = src;
                    switch (remaining) {
                        case 1:  pipeline->push_back({ProgramOp::copy_uniform,    ctx}); break;
                        case 2:  pipeline->push_back({ProgramOp::copy_2_uniforms, ctx}); break;
                        case 3:  pipeline->push_back({ProgramOp::copy_3_uniforms, ctx}); break;
                        default: pipeline->push_back({ProgramOp::copy_4_uniforms, ctx}); break;
                    }
                    dst += 4 * N;
                    src += 4;
                }
                break;
            }
            case BuilderOp::push_condition_mask: {
                float* dst = tempStackPtr;
                pipeline->push_back({ProgramOp::store_condition_mask, dst});
                break;
            }
            case BuilderOp::pop_condition_mask: {
                float* src = tempStackPtr - (1 * N);
                pipeline->push_back({ProgramOp::load_condition_mask, src});
                break;
            }
            case BuilderOp::merge_condition_mask:
            case BuilderOp::merge_inv_condition_mask: {
                float* ptr = tempStackPtr - (2 * N);
                pipeline->push_back({(ProgramOp)inst.fOp, ptr});
                break;
            }
            case BuilderOp::push_loop_mask: {
                float* dst = tempStackPtr;
                pipeline->push_back({ProgramOp::store_loop_mask, dst});
                break;
            }
            case BuilderOp::pop_loop_mask: {
                float* src = tempStackPtr - (1 * N);
                pipeline->push_back({ProgramOp::load_loop_mask, src});
                break;
            }
            case BuilderOp::pop_and_reenable_loop_mask: {
                float* src = tempStackPtr - (1 * N);
                pipeline->push_back({ProgramOp::reenable_loop_mask, src});
                break;
            }
            case BuilderOp::reenable_loop_mask:
                pipeline->push_back({ProgramOp::reenable_loop_mask, SlotA()});
                break;

            case BuilderOp::mask_off_loop_mask:
                pipeline->push_back({ProgramOp::mask_off_loop_mask, nullptr});
                break;

            case BuilderOp::merge_loop_mask: {
                float* src = tempStackPtr - (1 * N);
                pipeline->push_back({ProgramOp::merge_loop_mask, src});
                break;
            }
            case BuilderOp::push_return_mask: {
                float* dst = tempStackPtr;
                pipeline->push_back({ProgramOp::store_return_mask, dst});
                break;
            }
            case BuilderOp::pop_return_mask: {
                float* src = tempStackPtr - (1 * N);
                pipeline->push_back({ProgramOp::load_return_mask, src});
                break;
            }
            case BuilderOp::mask_off_return_mask:
                pipeline->push_back({ProgramOp::mask_off_return_mask, nullptr});
                break;

            case BuilderOp::copy_constant:
            case BuilderOp::push_constant: {
                float* dst = (inst.fOp == BuilderOp::copy_constant) ? SlotA() : tempStackPtr;
                // Splat constant values onto the stack.
                for (int remaining = inst.fImmA; remaining > 0; remaining -= 4) {
                    SkRasterPipeline_ConstantCtx ctx;
                    ctx.dst = OffsetFromBase(dst);
                    ctx.value = sk_bit_cast<float>(inst.fImmB);
                    void* ptr = SkRPCtxUtils::Pack(ctx, alloc);
                    switch (remaining) {
                        case 1:  pipeline->push_back({ProgramOp::copy_constant,    ptr}); break;
                        case 2:  pipeline->push_back({ProgramOp::splat_2_constants,ptr}); break;
                        case 3:  pipeline->push_back({ProgramOp::splat_3_constants,ptr}); break;
                        default: pipeline->push_back({ProgramOp::splat_4_constants,ptr}); break;
                    }
                    dst += 4 * N;
                }
                break;
            }
            case BuilderOp::copy_stack_to_slots: {
                float* src = tempStackPtr - (inst.fImmB * N);
                this->appendCopySlotsMasked(pipeline, alloc,
                                            OffsetFromBase(SlotA()),
                                            OffsetFromBase(src),
                                            inst.fImmA);
                break;
            }
            case BuilderOp::copy_stack_to_slots_unmasked: {
                float* src = tempStackPtr - (inst.fImmB * N);
                this->appendCopySlotsUnmasked(pipeline, alloc,
                                              OffsetFromBase(SlotA()),
                                              OffsetFromBase(src),
                                              inst.fImmA);
                break;
            }
            case BuilderOp::swizzle_copy_stack_to_slots: {
                // SlotA: fixed-range start
                // immA: number of swizzle components
                // immB: swizzle components
                // immC: offset from stack top
                auto stage = (ProgramOp)((int)ProgramOp::swizzle_copy_slot_masked + inst.fImmA - 1);
                auto* ctx = alloc->make<SkRasterPipeline_SwizzleCopyCtx>();
                ctx->src = tempStackPtr - (inst.fImmC * N);
                ctx->dst = SlotA();
                unpack_nybbles_to_offsets(inst.fImmB, SkSpan(ctx->offsets));
                pipeline->push_back({stage, ctx});
                break;
            }
            case BuilderOp::push_clone: {
                float* src = tempStackPtr - (inst.fImmB * N);
                float* dst = tempStackPtr;
                this->appendCopySlotsUnmasked(pipeline, alloc,
                                              OffsetFromBase(dst),
                                              OffsetFromBase(src),
                                              inst.fImmA);
                break;
            }
            case BuilderOp::push_clone_from_stack: {
                // immA: number of slots
                // immB: other stack ID
                // immC: offset from stack top
                float* sourceStackPtr = tempStackMap[inst.fImmB];
                float* src = sourceStackPtr - (inst.fImmC * N);
                float* dst = tempStackPtr;
                this->appendCopySlotsUnmasked(pipeline, alloc,
                                              OffsetFromBase(dst),
                                              OffsetFromBase(src),
                                              inst.fImmA);
                break;
            }
            case BuilderOp::push_clone_indirect_from_stack: {
                // immA: number of slots
                // immB: other stack ID
                // immC: offset from stack top
                // immD: dynamic stack ID
                float* sourceStackPtr = tempStackMap[inst.fImmB];

                auto* ctx = alloc->make<SkRasterPipeline_CopyIndirectCtx>();
                ctx->dst = tempStackPtr;
                ctx->src = sourceStackPtr - (inst.fImmC * N);
                ctx->indirectOffset =
                        reinterpret_cast<const uint32_t*>(tempStackMap[inst.fImmD]) - (1 * N);
                ctx->indirectLimit = inst.fImmC - inst.fImmA;
                ctx->slots = inst.fImmA;
                pipeline->push_back({ProgramOp::copy_from_indirect_unmasked, ctx});
                break;
            }
            case BuilderOp::swizzle_copy_stack_to_slots_indirect: {
                // SlotA: fixed-range start
                // SlotB: limit-range end
                // immA: number of swizzle components
                // immB: swizzle components
                // immC: offset from stack top
                // immD: dynamic stack ID
                auto* ctx = alloc->make<SkRasterPipeline_SwizzleCopyIndirectCtx>();
                ctx->src = tempStackPtr - (inst.fImmC * N);
                ctx->dst = SlotA();
                ctx->indirectOffset =
                        reinterpret_cast<const uint32_t*>(tempStackMap[inst.fImmD]) - (1 * N);
                ctx->indirectLimit =
                        inst.fSlotB - inst.fSlotA - (max_packed_nybble(inst.fImmB, inst.fImmA) + 1);
                ctx->slots = inst.fImmA;
                unpack_nybbles_to_offsets(inst.fImmB, SkSpan(ctx->offsets));
                pipeline->push_back({ProgramOp::swizzle_copy_to_indirect_masked, ctx});
                break;
            }
            case BuilderOp::case_op: {
                SkRasterPipeline_CaseOpCtx ctx;
                ctx.expectedValue = inst.fImmA;
                ctx.offset = OffsetFromBase(tempStackPtr - (2 * N));
                pipeline->push_back({ProgramOp::case_op, SkRPCtxUtils::Pack(ctx, alloc)});
                break;
            }
            case BuilderOp::continue_op:
                pipeline->push_back({ProgramOp::continue_op, tempStackMap[inst.fImmA] - (1 * N)});
                break;

            case BuilderOp::pad_stack:
            case BuilderOp::discard_stack:
                break;

            case BuilderOp::set_current_stack:
                currentStack = inst.fImmA;
                break;

            case BuilderOp::invoke_shader:
            case BuilderOp::invoke_color_filter:
            case BuilderOp::invoke_blender:
                pipeline->push_back({(ProgramOp)inst.fOp, context_bit_pun(inst.fImmA)});
                break;

            case BuilderOp::invoke_to_linear_srgb:
            case BuilderOp::invoke_from_linear_srgb:
                pipeline->push_back({(ProgramOp)inst.fOp, tempStackMap[inst.fImmA] - (4 * N)});
                break;

            case BuilderOp::trace_line: {
                auto* ctx = AllocTraceContext((SkRasterPipeline_TraceLineCtx*)nullptr);
                ctx->lineNumber = inst.fImmB;
                pipeline->push_back({ProgramOp::trace_line, ctx});
                break;
            }
            case BuilderOp::trace_scope: {
                auto* ctx = AllocTraceContext((SkRasterPipeline_TraceScopeCtx*)nullptr);
                ctx->delta = inst.fImmB;
                pipeline->push_back({ProgramOp::trace_scope, ctx});
                break;
            }
            case BuilderOp::trace_enter:
            case BuilderOp::trace_exit: {
                auto* ctx = AllocTraceContext((SkRasterPipeline_TraceFuncCtx*)nullptr);
                ctx->funcIdx = inst.fImmB;
                pipeline->push_back({(ProgramOp)inst.fOp, ctx});
                break;
            }
            case BuilderOp::trace_var:
            case BuilderOp::trace_var_indirect: {
                // SlotA: fixed-range start
                // SlotB: limit-range end
                // immA: trace-mask stack ID
                // immB: number of slots
                // immC: dynamic stack ID
                auto* ctx = AllocTraceContext((SkRasterPipeline_TraceVarCtx*)nullptr);
                ctx->slotIdx = inst.fSlotA;
                ctx->numSlots = inst.fImmB;
                ctx->data = reinterpret_cast<int*>(SlotA());
                if (inst.fOp == BuilderOp::trace_var_indirect) {
                    ctx->indirectOffset =
                            reinterpret_cast<const uint32_t*>(tempStackMap[inst.fImmC]) - (1 * N);
                    ctx->indirectLimit = inst.fSlotB - inst.fSlotA - inst.fImmB;
                } else {
                    ctx->indirectOffset = nullptr;
                    ctx->indirectLimit = 0;
                }
                pipeline->push_back({ProgramOp::trace_var, ctx});
                break;
            }
            default:
                SkDEBUGFAILF("Raster Pipeline: unsupported instruction %d", (int)inst.fOp);
                break;
        }

        int stackUsage = stack_usage(inst);
        if (stackUsage != 0) {
            tempStackPtr += stackUsage * N;
            SkASSERT(tempStackPtr >= slots.stack.begin());
            SkASSERT(tempStackPtr <= slots.stack.end());
        }

        // Periodically rewind the stack every 500 instructions. When SK_HAS_MUSTTAIL is set,
        // rewinds are not actually used; the appendStackRewind call becomes a no-op. On platforms
        // that don't support SK_HAS_MUSTTAIL, rewinding the stack periodically can prevent a
        // potential stack overflow when running a long program.
        int numPipelineStages = pipeline->size();
        if (numPipelineStages - mostRecentRewind > 500) {
            this->appendStackRewind(pipeline);
            mostRecentRewind = numPipelineStages;
        }
    }
}

// Finds duplicate names in the program and disambiguates them with subscripts.
TArray<std::string> build_unique_slot_name_list(const DebugTracePriv* debugTrace) {
    TArray<std::string> slotName;
    if (debugTrace) {
        slotName.reserve_exact(debugTrace->fSlotInfo.size());

        // The map consists of <variable name, <source position, unique name>>.
        THashMap<std::string_view, THashMap<int, std::string>> uniqueNameMap;

        for (const SlotDebugInfo& slotInfo : debugTrace->fSlotInfo) {
            // Look up this variable by its name and source position.
            int pos = slotInfo.pos.valid() ? slotInfo.pos.startOffset() : 0;
            THashMap<int, std::string>& positionMap = uniqueNameMap[slotInfo.name];
            std::string& uniqueName = positionMap[pos];

            // Have we seen this variable name/position combination before?
            if (uniqueName.empty()) {
                // This is a unique name/position pair.
                uniqueName = slotInfo.name;

                // But if it's not a unique _name_, it deserves a subscript to disambiguate it.
                int subscript = positionMap.count() - 1;
                if (subscript > 0) {
                    for (char digit : std::to_string(subscript)) {
                        // U+2080 through U+2089 (₀₁₂₃₄₅₆₇₈₉) in UTF8:
                        uniqueName.push_back((char)0xE2);
                        uniqueName.push_back((char)0x82);
                        uniqueName.push_back((char)(0x80 + digit - '0'));
                    }
                }
            }

            slotName.push_back(uniqueName);
        }
    }
    return slotName;
}

void Program::dump(SkWStream* out) const {
    // Allocate memory for the slot and uniform data, even though the program won't ever be
    // executed. The program requires pointer ranges for managing its data, and ASAN will report
    // errors if those pointers are pointing at unallocated memory.
    SkArenaAlloc alloc(/*firstHeapAllocation=*/1000);
    const int N = SkOpts::raster_pipeline_highp_stride;
    SlotData slots = this->allocateSlotData(&alloc);
    float* uniformPtr = alloc.makeArray<float>(fNumUniformSlots);
    SkSpan<float> uniforms = SkSpan(uniformPtr, fNumUniformSlots);

    // Turn this program into an array of Raster Pipeline stages.
    TArray<Stage> stages;
    this->makeStages(&stages, &alloc, uniforms, slots);

    // Find the labels in the program, and keep track of their offsets.
    THashMap<int, int> labelToStageMap; // <label ID, stage index>
    for (int index = 0; index < stages.size(); ++index) {
        if (stages[index].op == ProgramOp::label) {
            int labelID = sk_bit_cast<intptr_t>(stages[index].ctx);
            SkASSERT(!labelToStageMap.find(labelID));
            labelToStageMap[labelID] = index;
        }
    }

    // Assign unique names to each variable slot; our trace might have multiple variables with the
    // same name, which can make a dump hard to read.
    TArray<std::string> slotName = build_unique_slot_name_list(fDebugTrace);

    // Emit the program's instruction list.
    for (int index = 0; index < stages.size(); ++index) {
        const Stage& stage = stages[index];

        // Interpret the context value as a branch offset.
        auto BranchOffset = [&](const SkRasterPipeline_BranchCtx* ctx) -> std::string {
            // The context's offset field contains a label ID
            int labelID = ctx->offset;
            SkASSERT(labelToStageMap.find(labelID));
            int labelIndex = labelToStageMap[labelID];
            return SkSL::String::printf("%+d (label %d at #%d)",
                                        labelIndex - index, labelID, labelIndex + 1);
        };

        // Print a 32-bit immediate value of unknown type (int/float).
        auto Imm = [&](float immFloat, bool showAsFloat = true) -> std::string {
            // Special case exact zero as "0" for readability (vs `0x00000000 (0.0)`).
            if (sk_bit_cast<int32_t>(immFloat) == 0) {
                return "0";
            }
            // Start with `0x3F800000` as a baseline.
            uint32_t immUnsigned;
            memcpy(&immUnsigned, &immFloat, sizeof(uint32_t));
            auto text = SkSL::String::printf("0x%08X", immUnsigned);

            // Extend it to `0x3F800000 (1.0)` for finite floating point values.
            if (showAsFloat && std::isfinite(immFloat)) {
                text += " (";
                text += skstd::to_string(immFloat);
                text += ")";
            }
            return text;
        };

        // Interpret the context pointer as a 32-bit immediate value of unknown type (int/float).
        auto ImmCtx = [&](const void* ctx, bool showAsFloat = true) -> std::string {
            float f;
            memcpy(&f, &ctx, sizeof(float));
            return Imm(f, showAsFloat);
        };

        // Print `1` for single slots and `1..3` for ranges of slots.
        auto AsRange = [](int first, int count) -> std::string {
            std::string text = std::to_string(first);
            if (count > 1) {
                text += ".." + std::to_string(first + count - 1);
            }
            return text;
        };

        // Come up with a reasonable name for a range of slots, e.g.:
        // `val`: slot range points at one variable, named val
        // `val(0..1)`: slot range points at the first and second slot of val (which has 3+ slots)
        // `foo, bar`: slot range fully covers two variables, named foo and bar
        // `foo(3), bar(0)`: slot range covers the fourth slot of foo and the first slot of bar
        auto SlotName = [&](SkSpan<const SlotDebugInfo> debugInfo,
                            SkSpan<const std::string> names,
                            SlotRange range) -> std::string {
            SkASSERT(range.index >= 0 && (range.index + range.count) <= (int)debugInfo.size());

            std::string text;
            auto separator = SkSL::String::Separator();
            while (range.count > 0) {
                const SlotDebugInfo& slotInfo = debugInfo[range.index];
                text += separator();
                text += names.empty() ? slotInfo.name : names[range.index];

                // Figure out how many slots we can chomp in this iteration.
                int entireVariable = slotInfo.columns * slotInfo.rows;
                int slotsToChomp = std::min(range.count, entireVariable - slotInfo.componentIndex);
                // If we aren't consuming an entire variable, from first slot to last...
                if (slotsToChomp != entireVariable) {
                    // ... decorate it with a range suffix.
                    text += "(" + AsRange(slotInfo.componentIndex, slotsToChomp) + ")";
                }
                range.index += slotsToChomp;
                range.count -= slotsToChomp;
            }

            return text;
        };

        // Attempts to interpret the passed-in pointer as a uniform range.
        auto UniformPtrCtx = [&](const float* ptr, int numSlots) -> std::string {
            const float* end = ptr + numSlots;
            if (ptr >= uniforms.begin() && end <= uniforms.end()) {
                int uniformIdx = ptr - uniforms.begin();
                if (fDebugTrace) {
                    // Handle pointers to named uniform slots.
                    std::string name = SlotName(fDebugTrace->fUniformInfo, /*names=*/{},
                                                {uniformIdx, numSlots});
                    if (!name.empty()) {
                        return name;
                    }
                }
                // Handle pointers to uniforms (when no debug info exists).
                return "u" + AsRange(uniformIdx, numSlots);
            }
            return {};
        };

        // Attempts to interpret the passed-in pointer as a value slot range.
        auto ValuePtrCtx = [&](const float* ptr, int numSlots) -> std::string {
            const float* end = ptr + (N * numSlots);
            if (ptr >= slots.values.begin() && end <= slots.values.end()) {
                int valueIdx = ptr - slots.values.begin();
                SkASSERT((valueIdx % N) == 0);
                valueIdx /= N;
                if (fDebugTrace) {
                    // Handle pointers to named value slots.
                    std::string name = SlotName(fDebugTrace->fSlotInfo, slotName,
                                                {valueIdx, numSlots});
                    if (!name.empty()) {
                        return name;
                    }
                }
                // Handle pointers to value slots (when no debug info exists).
                return "v" + AsRange(valueIdx, numSlots);
            }
            return {};
        };

        // Interpret the context value as a pointer to `count` immediate values.
        auto MultiImmCtx = [&](const float* ptr, int count) -> std::string {
            // If this is a uniform, print it by name.
            if (std::string text = UniformPtrCtx(ptr, count); !text.empty()) {
                return text;
            }
            // Emit a single unbracketed immediate.
            if (count == 1) {
                return Imm(*ptr);
            }
            // Emit a list like `[0x00000000 (0.0), 0x3F80000 (1.0)]`.
            std::string text = "[";
            auto separator = SkSL::String::Separator();
            while (count--) {
                text += separator();
                text += Imm(*ptr++);
            }
            return text + "]";
        };

        // Interpret the context value as a generic pointer.
        auto PtrCtx = [&](const void* ctx, int numSlots) -> std::string {
            const float *ctxAsSlot = static_cast<const float*>(ctx);
            // Check for uniform and value pointers.
            if (std::string uniform = UniformPtrCtx(ctxAsSlot, numSlots); !uniform.empty()) {
                return uniform;
            }
            if (std::string value = ValuePtrCtx(ctxAsSlot, numSlots); !value.empty()) {
                return value;
            }
            // Handle pointers to temporary stack slots.
            if (ctxAsSlot >= slots.stack.begin() && ctxAsSlot < slots.stack.end()) {
                int stackIdx = ctxAsSlot - slots.stack.begin();
                SkASSERT((stackIdx % N) == 0);
                return "$" + AsRange(stackIdx / N, numSlots);
            }
            // This pointer is out of our expected bounds; this generally isn't expected to happen.
            return "ExternalPtr(" + AsRange(0, numSlots) + ")";
        };

        // Converts an RP offset to a pointer.
        auto OffsetToPtr = [&](SkRPOffset offset) -> std::byte* {
            return (std::byte*)slots.values.data() + offset;
        };

        // Interprets a slab offset as a slot range.
        auto OffsetCtx = [&](SkRPOffset offset, int numSlots) -> std::string {
            return PtrCtx(OffsetToPtr(offset), numSlots);
        };

        // Interpret the context value as a pointer to two adjacent values.
        auto AdjacentPtrCtx = [&](const void* ctx,
                                  int numSlots) -> std::tuple<std::string, std::string> {
            const float *ctxAsSlot = static_cast<const float*>(ctx);
            return std::make_tuple(PtrCtx(ctxAsSlot, numSlots),
                                   PtrCtx(ctxAsSlot + (N * numSlots), numSlots));
        };

        // Interprets a slab offset as two adjacent slot ranges.
        auto AdjacentOffsetCtx = [&](SkRPOffset offset,
                                     int numSlots) -> std::tuple<std::string, std::string> {
            return AdjacentPtrCtx((std::byte*)slots.values.data() + offset, numSlots);
        };

        // Interpret the context value as a pointer to three adjacent values.
        auto Adjacent3PtrCtx = [&](const void* ctx, int numSlots) ->
                                  std::tuple<std::string, std::string, std::string> {
            const float *ctxAsSlot = static_cast<const float*>(ctx);
            return std::make_tuple(PtrCtx(ctxAsSlot, numSlots),
                                   PtrCtx(ctxAsSlot + (N * numSlots), numSlots),
                                   PtrCtx(ctxAsSlot + (2 * N * numSlots), numSlots));
        };

        // Interprets a slab offset as three adjacent slot ranges.
        auto Adjacent3OffsetCtx = [&](SkRPOffset offset, int numSlots) ->
                                     std::tuple<std::string, std::string, std::string> {
            return Adjacent3PtrCtx((std::byte*)slots.values.data() + offset, numSlots);
        };

        // Interpret the context value as a BinaryOp structure for copy_n_slots (numSlots is
        // dictated by the op itself).
        auto BinaryOpCtx = [&](const void* v,
                               int numSlots) -> std::tuple<std::string, std::string> {
            auto ctx = SkRPCtxUtils::Unpack((const SkRasterPipeline_BinaryOpCtx*)v);
            return std::make_tuple(OffsetCtx(ctx.dst, numSlots),
                                   OffsetCtx(ctx.src, numSlots));
        };

        // Interpret the context value as a BinaryOp structure for copy_n_uniforms (numSlots is
        // dictated by the op itself).
        auto CopyUniformCtx = [&](const void* v,
                                  int numSlots) -> std::tuple<std::string, std::string> {
            const auto *ctx = static_cast<const SkRasterPipeline_UniformCtx*>(v);
            return std::make_tuple(PtrCtx(ctx->dst, numSlots),
                                   MultiImmCtx(ctx->src, numSlots));
        };

        // Interpret the context value as a BinaryOp structure (numSlots is inferred from the
        // distance between pointers).
        auto AdjacentBinaryOpCtx = [&](const void* v) -> std::tuple<std::string, std::string> {
            auto ctx = SkRPCtxUtils::Unpack((const SkRasterPipeline_BinaryOpCtx*)v);
            int numSlots = (ctx.src - ctx.dst) / (N * sizeof(float));
            return AdjacentOffsetCtx(ctx.dst, numSlots);
        };

        // Interpret the context value as a TernaryOp structure (numSlots is inferred from `delta`).
        auto AdjacentTernaryOpCtx = [&](const void* v) ->
                                       std::tuple<std::string, std::string, std::string> {
            auto ctx = SkRPCtxUtils::Unpack((const SkRasterPipeline_TernaryOpCtx*)v);
            int numSlots = ctx.delta / (sizeof(float) * N);
            return Adjacent3OffsetCtx(ctx.dst, numSlots);
        };

        // Stringize a span of swizzle offsets to the textual equivalent (`xyzw`).
        auto SwizzleOffsetSpan = [&](const auto offsets) {
            std::string src;
            for (uint16_t offset : offsets) {
                if (offset == (0 * N * sizeof(float))) {
                    src.push_back('x');
                } else if (offset == (1 * N * sizeof(float))) {
                    src.push_back('y');
                } else if (offset == (2 * N * sizeof(float))) {
                    src.push_back('z');
                } else if (offset == (3 * N * sizeof(float))) {
                    src.push_back('w');
                } else {
                    src.push_back('?');
                }
            }
            return src;
        };

        // When we decode a swizzle, we don't know the slot width of the original value; that's not
        // preserved in the instruction encoding. (e.g., myFloat4.y would be indistinguishable from
        // myFloat2.y.) We do our best to make a readable dump using the data we have.
        auto SwizzleWidth = [&](const auto offsets) {
            size_t highestComponent = *std::max_element(offsets.begin(), offsets.end()) /
                                      (N * sizeof(float));
            size_t swizzleWidth = offsets.size();
            return std::max(swizzleWidth, highestComponent + 1);
        };

        // Stringize a swizzled pointer.
        auto SwizzlePtr = [&](const void* ptr, const auto offsets) {
            return "(" + PtrCtx(ptr, SwizzleWidth(SkSpan(offsets))) + ")." +
                   SwizzleOffsetSpan(SkSpan(offsets));
        };

        // Interpret the context value as a Swizzle structure.
        auto SwizzleCtx = [&](ProgramOp op, const void* v) -> std::tuple<std::string, std::string> {
            auto ctx = SkRPCtxUtils::Unpack((const SkRasterPipeline_SwizzleCtx*)v);
            int destSlots = (int)op - (int)BuilderOp::swizzle_1 + 1;
            return std::make_tuple(
                    OffsetCtx(ctx.dst, destSlots),
                    SwizzlePtr(OffsetToPtr(ctx.dst), SkSpan(ctx.offsets, destSlots)));
        };

        // Interpret the context value as a SwizzleCopy structure.
        auto SwizzleCopyCtx = [&](ProgramOp op,
                                  const void* v) -> std::tuple<std::string, std::string> {
            const auto* ctx = static_cast<const SkRasterPipeline_SwizzleCopyCtx*>(v);
            int destSlots = (int)op - (int)BuilderOp::swizzle_copy_slot_masked + 1;

            return std::make_tuple(SwizzlePtr(ctx->dst, SkSpan(ctx->offsets, destSlots)),
                                   PtrCtx(ctx->src, destSlots));
        };

        // Interpret the context value as a Shuffle structure.
        auto ShuffleCtx = [&](const void* v) -> std::tuple<std::string, std::string> {
            const auto* ctx = static_cast<const SkRasterPipeline_ShuffleCtx*>(v);

            std::string dst = PtrCtx(ctx->ptr, ctx->count);
            std::string src = "(" + dst + ")[";
            for (int index = 0; index < ctx->count; ++index) {
                if (ctx->offsets[index] % (N * sizeof(float))) {
                    src.push_back('?');
                } else {
                    src += std::to_string(ctx->offsets[index] / (N * sizeof(float)));
                }
                src.push_back(' ');
            }
            src.back() = ']';
            return std::make_tuple(dst, src);
        };

        // Interpret the context value as a packed ConstantCtx structure.
        auto ConstantCtx = [&](const void* v,
                               int slots,
                               bool showAsFloat = true) -> std::tuple<std::string, std::string> {
            auto ctx = SkRPCtxUtils::Unpack((const SkRasterPipeline_ConstantCtx*)v);
            return std::make_tuple(OffsetCtx(ctx.dst, slots),
                                   Imm(ctx.value, showAsFloat));
        };

        std::string opArg1, opArg2, opArg3, opSwizzle;
        using POp = ProgramOp;
        switch (stage.op) {
            case POp::label:
            case POp::invoke_shader:
            case POp::invoke_color_filter:
            case POp::invoke_blender:
                opArg1 = ImmCtx(stage.ctx, /*showAsFloat=*/false);
                break;

            case POp::case_op: {
                auto ctx = SkRPCtxUtils::Unpack((const SkRasterPipeline_CaseOpCtx*)stage.ctx);
                opArg1 = OffsetCtx(ctx.offset, 1);
                opArg2 = OffsetCtx(ctx.offset + sizeof(int32_t) * N, 1);
                opArg3 = Imm(sk_bit_cast<float>(ctx.expectedValue), /*showAsFloat=*/false);
                break;
            }
            case POp::swizzle_1:
            case POp::swizzle_2:
            case POp::swizzle_3:
            case POp::swizzle_4:
                std::tie(opArg1, opArg2) = SwizzleCtx(stage.op, stage.ctx);
                break;

            case POp::swizzle_copy_slot_masked:
            case POp::swizzle_copy_2_slots_masked:
            case POp::swizzle_copy_3_slots_masked:
            case POp::swizzle_copy_4_slots_masked:
                std::tie(opArg1, opArg2) = SwizzleCopyCtx(stage.op, stage.ctx);
                break;

            case POp::refract_4_floats:
                std::tie(opArg1, opArg2) = AdjacentPtrCtx(stage.ctx, 4);
                opArg3 = PtrCtx((const float*)(stage.ctx) + (8 * N), 1);
                break;

            case POp::dot_2_floats:
                opArg1 = PtrCtx(stage.ctx, 1);
                std::tie(opArg2, opArg3) = AdjacentPtrCtx(stage.ctx, 2);
                break;

            case POp::dot_3_floats:
                opArg1 = PtrCtx(stage.ctx, 1);
                std::tie(opArg2, opArg3) = AdjacentPtrCtx(stage.ctx, 3);
                break;

            case POp::dot_4_floats:
                opArg1 = PtrCtx(stage.ctx, 1);
                std::tie(opArg2, opArg3) = AdjacentPtrCtx(stage.ctx, 4);
                break;

            case POp::shuffle:
                std::tie(opArg1, opArg2) = ShuffleCtx(stage.ctx);
                break;

            case POp::matrix_multiply_2:
            case POp::matrix_multiply_3:
            case POp::matrix_multiply_4: {
                auto ctx =
                        SkRPCtxUtils::Unpack((const SkRasterPipeline_MatrixMultiplyCtx*)stage.ctx);
                int leftMatrix = ctx.leftColumns * ctx.leftRows;
                int rightMatrix = ctx.rightColumns * ctx.rightRows;
                int resultMatrix = ctx.rightColumns * ctx.leftRows;
                SkRPOffset leftOffset =
                        ctx.dst + (ctx.rightColumns * ctx.leftRows * sizeof(float) * N);
                SkRPOffset rightOffset =
                        leftOffset + (ctx.leftColumns * ctx.leftRows * sizeof(float) * N);
                opArg1 = SkSL::String::printf("mat%dx%x(%s)",
                                              ctx.rightColumns,
                                              ctx.leftRows,
                                              OffsetCtx(ctx.dst, resultMatrix).c_str());
                opArg2 = SkSL::String::printf("mat%dx%x(%s)",
                                              ctx.leftColumns,
                                              ctx.leftRows,
                                              OffsetCtx(leftOffset, leftMatrix).c_str());
                opArg3 = SkSL::String::printf("mat%dx%x(%s)",
                                              ctx.rightColumns,
                                              ctx.rightRows,
                                              OffsetCtx(rightOffset, rightMatrix).c_str());
                break;
            }
            case POp::load_condition_mask:
            case POp::store_condition_mask:
            case POp::load_loop_mask:
            case POp::store_loop_mask:
            case POp::merge_loop_mask:
            case POp::reenable_loop_mask:
            case POp::load_return_mask:
            case POp::store_return_mask:
            case POp::continue_op:
            case POp::cast_to_float_from_int: case POp::cast_to_float_from_uint:
            case POp::cast_to_int_from_float: case POp::cast_to_uint_from_float:
            case POp::abs_int:
            case POp::acos_float:
            case POp::asin_float:
            case POp::atan_float:
            case POp::ceil_float:
            case POp::cos_float:
            case POp::exp_float:
            case POp::exp2_float:
            case POp::log_float:
            case POp::log2_float:
            case POp::floor_float:
            case POp::invsqrt_float:
            case POp::sin_float:
            case POp::sqrt_float:
            case POp::tan_float:
                opArg1 = PtrCtx(stage.ctx, 1);
                break;

            case POp::store_src_rg:
            case POp::cast_to_float_from_2_ints: case POp::cast_to_float_from_2_uints:
            case POp::cast_to_int_from_2_floats: case POp::cast_to_uint_from_2_floats:
            case POp::abs_2_ints:
            case POp::ceil_2_floats:
            case POp::floor_2_floats:
            case POp::invsqrt_2_floats:
                opArg1 = PtrCtx(stage.ctx, 2);
                break;

            case POp::cast_to_float_from_3_ints: case POp::cast_to_float_from_3_uints:
            case POp::cast_to_int_from_3_floats: case POp::cast_to_uint_from_3_floats:
            case POp::abs_3_ints:
            case POp::ceil_3_floats:
            case POp::floor_3_floats:
            case POp::invsqrt_3_floats:
                opArg1 = PtrCtx(stage.ctx, 3);
                break;

            case POp::load_src:
            case POp::load_dst:
            case POp::exchange_src:
            case POp::store_src:
            case POp::store_dst:
            case POp::store_device_xy01:
            case POp::invoke_to_linear_srgb:
            case POp::invoke_from_linear_srgb:
            case POp::cast_to_float_from_4_ints: case POp::cast_to_float_from_4_uints:
            case POp::cast_to_int_from_4_floats: case POp::cast_to_uint_from_4_floats:
            case POp::abs_4_ints:
            case POp::ceil_4_floats:
            case POp::floor_4_floats:
            case POp::invsqrt_4_floats:
            case POp::inverse_mat2:
                opArg1 = PtrCtx(stage.ctx, 4);
                break;

            case POp::inverse_mat3:
                opArg1 = PtrCtx(stage.ctx, 9);
                break;

            case POp::inverse_mat4:
                opArg1 = PtrCtx(stage.ctx, 16);
                break;

            case POp::copy_constant:
            case POp::add_imm_float:
            case POp::mul_imm_float:
            case POp::cmple_imm_float:
            case POp::cmplt_imm_float:
            case POp::cmpeq_imm_float:
            case POp::cmpne_imm_float:
            case POp::min_imm_float:
            case POp::max_imm_float:
                std::tie(opArg1, opArg2) = ConstantCtx(stage.ctx, 1);
                break;

            case POp::add_imm_int:
            case POp::mul_imm_int:
            case POp::bitwise_and_imm_int:
            case POp::bitwise_xor_imm_int:
            case POp::cmple_imm_int:
            case POp::cmple_imm_uint:
            case POp::cmplt_imm_int:
            case POp::cmplt_imm_uint:
            case POp::cmpeq_imm_int:
            case POp::cmpne_imm_int:
                std::tie(opArg1, opArg2) = ConstantCtx(stage.ctx, 1, /*showAsFloat=*/false);
                break;

            case POp::splat_2_constants:
            case POp::bitwise_and_imm_2_ints:
                std::tie(opArg1, opArg2) = ConstantCtx(stage.ctx, 2);
                break;

            case POp::splat_3_constants:
            case POp::bitwise_and_imm_3_ints:
                std::tie(opArg1, opArg2) = ConstantCtx(stage.ctx, 3);
                break;

            case POp::splat_4_constants:
            case POp::bitwise_and_imm_4_ints:
                std::tie(opArg1, opArg2) = ConstantCtx(stage.ctx, 4);
                break;

            case POp::copy_uniform:
                std::tie(opArg1, opArg2) = CopyUniformCtx(stage.ctx, 1);
                break;

            case POp::copy_2_uniforms:
                std::tie(opArg1, opArg2) = CopyUniformCtx(stage.ctx, 2);
                break;

            case POp::copy_3_uniforms:
                std::tie(opArg1, opArg2) = CopyUniformCtx(stage.ctx, 3);
                break;

            case POp::copy_4_uniforms:
                std::tie(opArg1, opArg2) = CopyUniformCtx(stage.ctx, 4);
                break;

            case POp::copy_slot_masked:
            case POp::copy_slot_unmasked:
                std::tie(opArg1, opArg2) = BinaryOpCtx(stage.ctx, 1);
                break;

            case POp::copy_2_slots_masked:
            case POp::copy_2_slots_unmasked:
                std::tie(opArg1, opArg2) = BinaryOpCtx(stage.ctx, 2);
                break;

            case POp::copy_3_slots_masked:
            case POp::copy_3_slots_unmasked:
                std::tie(opArg1, opArg2) = BinaryOpCtx(stage.ctx, 3);
                break;

            case POp::copy_4_slots_masked:
            case POp::copy_4_slots_unmasked:
                std::tie(opArg1, opArg2) = BinaryOpCtx(stage.ctx, 4);
                break;

            case POp::copy_from_indirect_unmasked:
            case POp::copy_to_indirect_masked: {
                const auto* ctx = static_cast<SkRasterPipeline_CopyIndirectCtx*>(stage.ctx);
                // We don't incorporate the indirect-limit in the output
                opArg1 = PtrCtx(ctx->dst, ctx->slots);
                opArg2 = PtrCtx(ctx->src, ctx->slots);
                opArg3 = PtrCtx(ctx->indirectOffset, 1);
                break;
            }
            case POp::copy_from_indirect_uniform_unmasked: {
                const auto* ctx = static_cast<SkRasterPipeline_CopyIndirectCtx*>(stage.ctx);
                opArg1 = PtrCtx(ctx->dst, ctx->slots);
                opArg2 = UniformPtrCtx(ctx->src, ctx->slots);
                opArg3 = PtrCtx(ctx->indirectOffset, 1);
                break;
            }
            case POp::swizzle_copy_to_indirect_masked: {
                const auto* ctx = static_cast<SkRasterPipeline_SwizzleCopyIndirectCtx*>(stage.ctx);
                opArg1 = PtrCtx(ctx->dst, SwizzleWidth(SkSpan(ctx->offsets, ctx->slots)));
                opArg2 = PtrCtx(ctx->src, ctx->slots);
                opArg3 = PtrCtx(ctx->indirectOffset, 1);
                opSwizzle = SwizzleOffsetSpan(SkSpan(ctx->offsets, ctx->slots));
                break;
            }
            case POp::merge_condition_mask:
            case POp::merge_inv_condition_mask:
            case POp::add_float:   case POp::add_int:
            case POp::sub_float:   case POp::sub_int:
            case POp::mul_float:   case POp::mul_int:
            case POp::div_float:   case POp::div_int:   case POp::div_uint:
                                   case POp::bitwise_and_int:
                                   case POp::bitwise_or_int:
                                   case POp::bitwise_xor_int:
            case POp::mod_float:
            case POp::min_float:   case POp::min_int:   case POp::min_uint:
            case POp::max_float:   case POp::max_int:   case POp::max_uint:
            case POp::cmplt_float: case POp::cmplt_int: case POp::cmplt_uint:
            case POp::cmple_float: case POp::cmple_int: case POp::cmple_uint:
            case POp::cmpeq_float: case POp::cmpeq_int:
            case POp::cmpne_float: case POp::cmpne_int:
                std::tie(opArg1, opArg2) = AdjacentPtrCtx(stage.ctx, 1);
                break;

            case POp::mix_float:   case POp::mix_int:
                std::tie(opArg1, opArg2, opArg3) = Adjacent3PtrCtx(stage.ctx, 1);
                break;

            case POp::add_2_floats:   case POp::add_2_ints:
            case POp::sub_2_floats:   case POp::sub_2_ints:
            case POp::mul_2_floats:   case POp::mul_2_ints:
            case POp::div_2_floats:   case POp::div_2_ints:   case POp::div_2_uints:
                                      case POp::bitwise_and_2_ints:
                                      case POp::bitwise_or_2_ints:
                                      case POp::bitwise_xor_2_ints:
            case POp::mod_2_floats:
            case POp::min_2_floats:   case POp::min_2_ints:   case POp::min_2_uints:
            case POp::max_2_floats:   case POp::max_2_ints:   case POp::max_2_uints:
            case POp::cmplt_2_floats: case POp::cmplt_2_ints: case POp::cmplt_2_uints:
            case POp::cmple_2_floats: case POp::cmple_2_ints: case POp::cmple_2_uints:
            case POp::cmpeq_2_floats: case POp::cmpeq_2_ints:
            case POp::cmpne_2_floats: case POp::cmpne_2_ints:
                std::tie(opArg1, opArg2) = AdjacentPtrCtx(stage.ctx, 2);
                break;

            case POp::mix_2_floats:   case POp::mix_2_ints:
                std::tie(opArg1, opArg2, opArg3) = Adjacent3PtrCtx(stage.ctx, 2);
                break;

            case POp::add_3_floats:   case POp::add_3_ints:
            case POp::sub_3_floats:   case POp::sub_3_ints:
            case POp::mul_3_floats:   case POp::mul_3_ints:
            case POp::div_3_floats:   case POp::div_3_ints:   case POp::div_3_uints:
                                      case POp::bitwise_and_3_ints:
                                      case POp::bitwise_or_3_ints:
                                      case POp::bitwise_xor_3_ints:
            case POp::mod_3_floats:
            case POp::min_3_floats:   case POp::min_3_ints:   case POp::min_3_uints:
            case POp::max_3_floats:   case POp::max_3_ints:   case POp::max_3_uints:
            case POp::cmplt_3_floats: case POp::cmplt_3_ints: case POp::cmplt_3_uints:
            case POp::cmple_3_floats: case POp::cmple_3_ints: case POp::cmple_3_uints:
            case POp::cmpeq_3_floats: case POp::cmpeq_3_ints:
            case POp::cmpne_3_floats: case POp::cmpne_3_ints:
                std::tie(opArg1, opArg2) = AdjacentPtrCtx(stage.ctx, 3);
                break;

            case POp::mix_3_floats:   case POp::mix_3_ints:
                std::tie(opArg1, opArg2, opArg3) = Adjacent3PtrCtx(stage.ctx, 3);
                break;

            case POp::add_4_floats:   case POp::add_4_ints:
            case POp::sub_4_floats:   case POp::sub_4_ints:
            case POp::mul_4_floats:   case POp::mul_4_ints:
            case POp::div_4_floats:   case POp::div_4_ints:   case POp::div_4_uints:
                                      case POp::bitwise_and_4_ints:
                                      case POp::bitwise_or_4_ints:
                                      case POp::bitwise_xor_4_ints:
            case POp::mod_4_floats:
            case POp::min_4_floats:   case POp::min_4_ints:   case POp::min_4_uints:
            case POp::max_4_floats:   case POp::max_4_ints:   case POp::max_4_uints:
            case POp::cmplt_4_floats: case POp::cmplt_4_ints: case POp::cmplt_4_uints:
            case POp::cmple_4_floats: case POp::cmple_4_ints: case POp::cmple_4_uints:
            case POp::cmpeq_4_floats: case POp::cmpeq_4_ints:
            case POp::cmpne_4_floats: case POp::cmpne_4_ints:
                std::tie(opArg1, opArg2) = AdjacentPtrCtx(stage.ctx, 4);
                break;

            case POp::mix_4_floats:   case POp::mix_4_ints:
                std::tie(opArg1, opArg2, opArg3) = Adjacent3PtrCtx(stage.ctx, 4);
                break;

            case POp::add_n_floats:   case POp::add_n_ints:
            case POp::sub_n_floats:   case POp::sub_n_ints:
            case POp::mul_n_floats:   case POp::mul_n_ints:
            case POp::div_n_floats:   case POp::div_n_ints:   case POp::div_n_uints:
                                      case POp::bitwise_and_n_ints:
                                      case POp::bitwise_or_n_ints:
                                      case POp::bitwise_xor_n_ints:
            case POp::mod_n_floats:
            case POp::min_n_floats:   case POp::min_n_ints:   case POp::min_n_uints:
            case POp::max_n_floats:   case POp::max_n_ints:   case POp::max_n_uints:
            case POp::cmplt_n_floats: case POp::cmplt_n_ints: case POp::cmplt_n_uints:
            case POp::cmple_n_floats: case POp::cmple_n_ints: case POp::cmple_n_uints:
            case POp::cmpeq_n_floats: case POp::cmpeq_n_ints:
            case POp::cmpne_n_floats: case POp::cmpne_n_ints:
            case POp::atan2_n_floats:
            case POp::pow_n_floats:
                std::tie(opArg1, opArg2) = AdjacentBinaryOpCtx(stage.ctx);
                break;

            case POp::mix_n_floats:        case POp::mix_n_ints:
            case POp::smoothstep_n_floats:
                std::tie(opArg1, opArg2, opArg3) = AdjacentTernaryOpCtx(stage.ctx);
                break;

            case POp::jump:
            case POp::branch_if_all_lanes_active:
            case POp::branch_if_any_lanes_active:
            case POp::branch_if_no_lanes_active:
                opArg1 = BranchOffset(static_cast<SkRasterPipeline_BranchCtx*>(stage.ctx));
                break;

            case POp::branch_if_no_active_lanes_eq: {
                const auto* ctx = static_cast<SkRasterPipeline_BranchIfEqualCtx*>(stage.ctx);
                opArg1 = BranchOffset(ctx);
                opArg2 = PtrCtx(ctx->ptr, 1);
                opArg3 = Imm(sk_bit_cast<float>(ctx->value));
                break;
            }
            case POp::trace_var: {
                const auto* ctx = static_cast<SkRasterPipeline_TraceVarCtx*>(stage.ctx);
                opArg1 = PtrCtx(ctx->traceMask, 1);
                opArg2 = PtrCtx(ctx->data, ctx->numSlots);
                if (ctx->indirectOffset != nullptr) {
                    opArg3 = " + " + PtrCtx(ctx->indirectOffset, 1);
                }
                break;
            }
            case POp::trace_line: {
                const auto* ctx = static_cast<SkRasterPipeline_TraceLineCtx*>(stage.ctx);
                opArg1 = PtrCtx(ctx->traceMask, 1);
                opArg2 = std::to_string(ctx->lineNumber);
                break;
            }
            case POp::trace_enter:
            case POp::trace_exit: {
                const auto* ctx = static_cast<SkRasterPipeline_TraceFuncCtx*>(stage.ctx);
                opArg1 = PtrCtx(ctx->traceMask, 1);
                opArg2 = (fDebugTrace &&
                          ctx->funcIdx >= 0 &&
                          ctx->funcIdx < (int)fDebugTrace->fFuncInfo.size())
                                 ? fDebugTrace->fFuncInfo[ctx->funcIdx].name
                                 : "???";
                break;
            }
            case POp::trace_scope: {
                const auto* ctx = static_cast<SkRasterPipeline_TraceScopeCtx*>(stage.ctx);
                opArg1 = PtrCtx(ctx->traceMask, 1);
                opArg2 = SkSL::String::printf("%+d", ctx->delta);
                break;
            }
            default:
                break;
        }

        std::string_view opName;
        switch (stage.op) {
        #define M(x) case POp::x: opName = #x; break;
            SK_RASTER_PIPELINE_OPS_ALL(M)
            SKRP_EXTENDED_OPS(M)
        #undef M
        }

        std::string opText;
        switch (stage.op) {
            case POp::trace_var:
                opText = "TraceVar(" + opArg2 + opArg3 + ") when " + opArg1 + " is true";
                break;

            case POp::trace_line:
                opText = "TraceLine(" + opArg2 + ") when " + opArg1 + " is true";
                break;

            case POp::trace_enter:
                opText = "TraceEnter(" + opArg2 + ") when " + opArg1 + " is true";
                break;

            case POp::trace_exit:
                opText = "TraceExit(" + opArg2 + ") when " + opArg1 + " is true";
                break;

            case POp::trace_scope:
                opText = "TraceScope(" + opArg2 + ") when " + opArg1 + " is true";
                break;

            case POp::init_lane_masks:
                opText = "CondMask = LoopMask = RetMask = true";
                break;

            case POp::load_condition_mask:
                opText = "CondMask = " + opArg1;
                break;

            case POp::store_condition_mask:
                opText = opArg1 + " = CondMask";
                break;

            case POp::merge_condition_mask:
                opText = "CondMask = " + opArg1 + " & " + opArg2;
                break;

            case POp::merge_inv_condition_mask:
                opText = "CondMask = " + opArg1 + " & ~" + opArg2;
                break;

            case POp::load_loop_mask:
                opText = "LoopMask = " + opArg1;
                break;

            case POp::store_loop_mask:
                opText = opArg1 + " = LoopMask";
                break;

            case POp::mask_off_loop_mask:
                opText = "LoopMask &= ~(CondMask & LoopMask & RetMask)";
                break;

            case POp::reenable_loop_mask:
                opText = "LoopMask |= " + opArg1;
                break;

            case POp::merge_loop_mask:
                opText = "LoopMask &= " + opArg1;
                break;

            case POp::load_return_mask:
                opText = "RetMask = " + opArg1;
                break;

            case POp::store_return_mask:
                opText = opArg1 + " = RetMask";
                break;

            case POp::mask_off_return_mask:
                opText = "RetMask &= ~(CondMask & LoopMask & RetMask)";
                break;

            case POp::store_src_rg:
                opText = opArg1 + " = src.rg";
                break;

            case POp::exchange_src:
                opText = "swap(src.rgba, " + opArg1 + ")";
                break;

            case POp::store_src:
                opText = opArg1 + " = src.rgba";
                break;

            case POp::store_dst:
                opText = opArg1 + " = dst.rgba";
                break;

            case POp::store_device_xy01:
                opText = opArg1 + " = DeviceCoords.xy01";
                break;

            case POp::load_src:
                opText = "src.rgba = " + opArg1;
                break;

            case POp::load_dst:
                opText = "dst.rgba = " + opArg1;
                break;

            case POp::bitwise_and_int:
            case POp::bitwise_and_2_ints:
            case POp::bitwise_and_3_ints:
            case POp::bitwise_and_4_ints:
            case POp::bitwise_and_n_ints:
            case POp::bitwise_and_imm_int:
            case POp::bitwise_and_imm_2_ints:
            case POp::bitwise_and_imm_3_ints:
            case POp::bitwise_and_imm_4_ints:
                opText = opArg1 + " &= " + opArg2;
                break;

            case POp::bitwise_or_int:
            case POp::bitwise_or_2_ints:
            case POp::bitwise_or_3_ints:
            case POp::bitwise_or_4_ints:
            case POp::bitwise_or_n_ints:
                opText = opArg1 + " |= " + opArg2;
                break;

            case POp::bitwise_xor_int:
            case POp::bitwise_xor_2_ints:
            case POp::bitwise_xor_3_ints:
            case POp::bitwise_xor_4_ints:
            case POp::bitwise_xor_n_ints:
            case POp::bitwise_xor_imm_int:
                opText = opArg1 + " ^= " + opArg2;
                break;

            case POp::cast_to_float_from_int:
            case POp::cast_to_float_from_2_ints:
            case POp::cast_to_float_from_3_ints:
            case POp::cast_to_float_from_4_ints:
                opText = opArg1 + " = IntToFloat(" + opArg1 + ")";
                break;

            case POp::cast_to_float_from_uint:
            case POp::cast_to_float_from_2_uints:
            case POp::cast_to_float_from_3_uints:
            case POp::cast_to_float_from_4_uints:
                opText = opArg1 + " = UintToFloat(" + opArg1 + ")";
                break;

            case POp::cast_to_int_from_float:
            case POp::cast_to_int_from_2_floats:
            case POp::cast_to_int_from_3_floats:
            case POp::cast_to_int_from_4_floats:
                opText = opArg1 + " = FloatToInt(" + opArg1 + ")";
                break;

            case POp::cast_to_uint_from_float:
            case POp::cast_to_uint_from_2_floats:
            case POp::cast_to_uint_from_3_floats:
            case POp::cast_to_uint_from_4_floats:
                opText = opArg1 + " = FloatToUint(" + opArg1 + ")";
                break;

            case POp::copy_slot_masked:            case POp::copy_2_slots_masked:
            case POp::copy_3_slots_masked:         case POp::copy_4_slots_masked:
            case POp::swizzle_copy_slot_masked:    case POp::swizzle_copy_2_slots_masked:
            case POp::swizzle_copy_3_slots_masked: case POp::swizzle_copy_4_slots_masked:
                opText = opArg1 + " = Mask(" + opArg2 + ")";
                break;

            case POp::copy_uniform:                case POp::copy_2_uniforms:
            case POp::copy_3_uniforms:             case POp::copy_4_uniforms:
            case POp::copy_slot_unmasked:          case POp::copy_2_slots_unmasked:
            case POp::copy_3_slots_unmasked:       case POp::copy_4_slots_unmasked:
            case POp::copy_constant:               case POp::splat_2_constants:
            case POp::splat_3_constants:           case POp::splat_4_constants:
            case POp::swizzle_1:                   case POp::swizzle_2:
            case POp::swizzle_3:                   case POp::swizzle_4:
            case POp::shuffle:
                opText = opArg1 + " = " + opArg2;
                break;

            case POp::copy_from_indirect_unmasked:
            case POp::copy_from_indirect_uniform_unmasked:
                opText = opArg1 + " = Indirect(" + opArg2 + " + " + opArg3 + ")";
                break;

            case POp::copy_to_indirect_masked:
                opText = "Indirect(" + opArg1 + " + " + opArg3 + ") = Mask(" + opArg2 + ")";
                break;

            case POp::swizzle_copy_to_indirect_masked:
                opText = "Indirect(" + opArg1 + " + " + opArg3 + ")." + opSwizzle + " = Mask(" +
                         opArg2 + ")";
                break;

            case POp::abs_int:
            case POp::abs_2_ints:
            case POp::abs_3_ints:
            case POp::abs_4_ints:
                opText = opArg1 + " = abs(" + opArg1 + ")";
                break;

            case POp::acos_float:
                opText = opArg1 + " = acos(" + opArg1 + ")";
                break;

            case POp::asin_float:
                opText = opArg1 + " = asin(" + opArg1 + ")";
                break;

            case POp::atan_float:
                opText = opArg1 + " = atan(" + opArg1 + ")";
                break;

            case POp::atan2_n_floats:
                opText = opArg1 + " = atan2(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::ceil_float:
            case POp::ceil_2_floats:
            case POp::ceil_3_floats:
            case POp::ceil_4_floats:
                opText = opArg1 + " = ceil(" + opArg1 + ")";
                break;

            case POp::cos_float:
                opText = opArg1 + " = cos(" + opArg1 + ")";
                break;

            case POp::refract_4_floats:
                opText = opArg1 + " = refract(" + opArg1 + ", " + opArg2 + ", " + opArg3 + ")";
                break;

            case POp::dot_2_floats:
            case POp::dot_3_floats:
            case POp::dot_4_floats:
                opText = opArg1 + " = dot(" + opArg2 + ", " + opArg3 + ")";
                break;

            case POp::exp_float:
                opText = opArg1 + " = exp(" + opArg1 + ")";
                break;

            case POp::exp2_float:
                opText = opArg1 + " = exp2(" + opArg1 + ")";
                break;

            case POp::log_float:
                opText = opArg1 + " = log(" + opArg1 + ")";
                break;

            case POp::log2_float:
                opText = opArg1 + " = log2(" + opArg1 + ")";
                break;

            case POp::pow_n_floats:
                opText = opArg1 + " = pow(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::sin_float:
                opText = opArg1 + " = sin(" + opArg1 + ")";
                break;

            case POp::sqrt_float:
                opText = opArg1 + " = sqrt(" + opArg1 + ")";
                break;

            case POp::tan_float:
                opText = opArg1 + " = tan(" + opArg1 + ")";
                break;

            case POp::floor_float:
            case POp::floor_2_floats:
            case POp::floor_3_floats:
            case POp::floor_4_floats:
                opText = opArg1 + " = floor(" + opArg1 + ")";
                break;

            case POp::invsqrt_float:
            case POp::invsqrt_2_floats:
            case POp::invsqrt_3_floats:
            case POp::invsqrt_4_floats:
                opText = opArg1 + " = inversesqrt(" + opArg1 + ")";
                break;

            case POp::inverse_mat2:
            case POp::inverse_mat3:
            case POp::inverse_mat4:
                opText = opArg1 + " = inverse(" + opArg1 + ")";
                break;

            case POp::add_float:     case POp::add_int:
            case POp::add_2_floats:  case POp::add_2_ints:
            case POp::add_3_floats:  case POp::add_3_ints:
            case POp::add_4_floats:  case POp::add_4_ints:
            case POp::add_n_floats:  case POp::add_n_ints:
            case POp::add_imm_float: case POp::add_imm_int:
                opText = opArg1 + " += " + opArg2;
                break;

            case POp::sub_float:    case POp::sub_int:
            case POp::sub_2_floats: case POp::sub_2_ints:
            case POp::sub_3_floats: case POp::sub_3_ints:
            case POp::sub_4_floats: case POp::sub_4_ints:
            case POp::sub_n_floats: case POp::sub_n_ints:
                opText = opArg1 + " -= " + opArg2;
                break;

            case POp::mul_float:     case POp::mul_int:
            case POp::mul_2_floats:  case POp::mul_2_ints:
            case POp::mul_3_floats:  case POp::mul_3_ints:
            case POp::mul_4_floats:  case POp::mul_4_ints:
            case POp::mul_n_floats:  case POp::mul_n_ints:
            case POp::mul_imm_float: case POp::mul_imm_int:
                opText = opArg1 + " *= " + opArg2;
                break;

            case POp::div_float:    case POp::div_int:    case POp::div_uint:
            case POp::div_2_floats: case POp::div_2_ints: case POp::div_2_uints:
            case POp::div_3_floats: case POp::div_3_ints: case POp::div_3_uints:
            case POp::div_4_floats: case POp::div_4_ints: case POp::div_4_uints:
            case POp::div_n_floats: case POp::div_n_ints: case POp::div_n_uints:
                opText = opArg1 + " /= " + opArg2;
                break;

            case POp::matrix_multiply_2:
            case POp::matrix_multiply_3:
            case POp::matrix_multiply_4:
                opText = opArg1 + " = " + opArg2 + " * " + opArg3;
                break;

            case POp::mod_float:
            case POp::mod_2_floats:
            case POp::mod_3_floats:
            case POp::mod_4_floats:
            case POp::mod_n_floats:
                opText = opArg1 + " = mod(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::min_float:        case POp::min_int:          case POp::min_uint:
            case POp::min_2_floats:     case POp::min_2_ints:       case POp::min_2_uints:
            case POp::min_3_floats:     case POp::min_3_ints:       case POp::min_3_uints:
            case POp::min_4_floats:     case POp::min_4_ints:       case POp::min_4_uints:
            case POp::min_n_floats:     case POp::min_n_ints:       case POp::min_n_uints:
            case POp::min_imm_float:
                opText = opArg1 + " = min(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::max_float:        case POp::max_int:          case POp::max_uint:
            case POp::max_2_floats:     case POp::max_2_ints:       case POp::max_2_uints:
            case POp::max_3_floats:     case POp::max_3_ints:       case POp::max_3_uints:
            case POp::max_4_floats:     case POp::max_4_ints:       case POp::max_4_uints:
            case POp::max_n_floats:     case POp::max_n_ints:       case POp::max_n_uints:
            case POp::max_imm_float:
                opText = opArg1 + " = max(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::cmplt_float:     case POp::cmplt_int:     case POp::cmplt_uint:
            case POp::cmplt_2_floats:  case POp::cmplt_2_ints:  case POp::cmplt_2_uints:
            case POp::cmplt_3_floats:  case POp::cmplt_3_ints:  case POp::cmplt_3_uints:
            case POp::cmplt_4_floats:  case POp::cmplt_4_ints:  case POp::cmplt_4_uints:
            case POp::cmplt_n_floats:  case POp::cmplt_n_ints:  case POp::cmplt_n_uints:
            case POp::cmplt_imm_float: case POp::cmplt_imm_int: case POp::cmplt_imm_uint:
                opText = opArg1 + " = lessThan(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::cmple_float:     case POp::cmple_int:     case POp::cmple_uint:
            case POp::cmple_2_floats:  case POp::cmple_2_ints:  case POp::cmple_2_uints:
            case POp::cmple_3_floats:  case POp::cmple_3_ints:  case POp::cmple_3_uints:
            case POp::cmple_4_floats:  case POp::cmple_4_ints:  case POp::cmple_4_uints:
            case POp::cmple_n_floats:  case POp::cmple_n_ints:  case POp::cmple_n_uints:
            case POp::cmple_imm_float: case POp::cmple_imm_int: case POp::cmple_imm_uint:
                opText = opArg1 + " = lessThanEqual(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::cmpeq_float:     case POp::cmpeq_int:
            case POp::cmpeq_2_floats:  case POp::cmpeq_2_ints:
            case POp::cmpeq_3_floats:  case POp::cmpeq_3_ints:
            case POp::cmpeq_4_floats:  case POp::cmpeq_4_ints:
            case POp::cmpeq_n_floats:  case POp::cmpeq_n_ints:
            case POp::cmpeq_imm_float: case POp::cmpeq_imm_int:
                opText = opArg1 + " = equal(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::cmpne_float:     case POp::cmpne_int:
            case POp::cmpne_2_floats:  case POp::cmpne_2_ints:
            case POp::cmpne_3_floats:  case POp::cmpne_3_ints:
            case POp::cmpne_4_floats:  case POp::cmpne_4_ints:
            case POp::cmpne_n_floats:  case POp::cmpne_n_ints:
            case POp::cmpne_imm_float: case POp::cmpne_imm_int:
                opText = opArg1 + " = notEqual(" + opArg1 + ", " + opArg2 + ")";
                break;

            case POp::mix_float:      case POp::mix_int:
            case POp::mix_2_floats:   case POp::mix_2_ints:
            case POp::mix_3_floats:   case POp::mix_3_ints:
            case POp::mix_4_floats:   case POp::mix_4_ints:
            case POp::mix_n_floats:   case POp::mix_n_ints:
                opText = opArg1 + " = mix(" + opArg2 + ", " + opArg3 + ", " + opArg1 + ")";
                break;

            case POp::smoothstep_n_floats:
                opText = opArg1 + " = smoothstep(" + opArg1 + ", " + opArg2 + ", " + opArg3 + ")";
                break;

            case POp::jump:
            case POp::branch_if_all_lanes_active:
            case POp::branch_if_any_lanes_active:
            case POp::branch_if_no_lanes_active:
            case POp::invoke_shader:
            case POp::invoke_color_filter:
            case POp::invoke_blender:
                opText = std::string(opName) + " " + opArg1;
                break;

            case POp::invoke_to_linear_srgb:
                opText = opArg1 + " = toLinearSrgb(" + opArg1 + ")";
                break;

            case POp::invoke_from_linear_srgb:
                opText = opArg1 + " = fromLinearSrgb(" + opArg1 + ")";
                break;

            case POp::branch_if_no_active_lanes_eq:
                opText = "branch " + opArg1 + " if no lanes of " + opArg2 + " == " + opArg3;
                break;

            case POp::label:
                opText = "label " + opArg1;
                break;

            case POp::case_op:
                opText = "if (" + opArg1 + " == " + opArg3 +
                         ") { LoopMask = true; " + opArg2 + " = false; }";
                break;

            case POp::continue_op:
                opText = opArg1 +
                         " |= Mask(0xFFFFFFFF); LoopMask &= ~(CondMask & LoopMask & RetMask)";
                break;

            default:
                break;
        }

        opName = opName.substr(0, 30);
        if (!opText.empty()) {
            out->writeText(SkSL::String::printf("%-30.*s %s\n",
                                                (int)opName.size(), opName.data(),
                                                opText.c_str()).c_str());
        } else {
            out->writeText(SkSL::String::printf("%.*s\n",
                                                (int)opName.size(), opName.data()).c_str());
        }
    }
}

}  // namespace SkSL::RP

#endif  // SK_ENABLE_SKSL_IN_RASTER_PIPELINE
