_Z6HexStr4SpanIKhE:
   30|  65.5k|{
   31|  65.5k|    std::string rv(s.size() * 2, '\0');
   32|  65.5k|    static constexpr auto byte_to_hex = CreateByteToHexMap();
   33|  65.5k|    static_assert(sizeof(byte_to_hex) == 512);
   34|       |
   35|  65.5k|    char* it = rv.data();
   36|  85.9k|    for (uint8_t v : s) {
  ------------------
  |  Branch (36:20): [True: 85.9k, False: 65.5k]
  ------------------
   37|  85.9k|        std::memcpy(it, byte_to_hex[v].data(), 2);
   38|  85.9k|        it += 2;
   39|  85.9k|    }
   40|       |
   41|  65.5k|    assert(it == rv.data() + rv.size());
   42|  65.5k|    return rv;
   43|  65.5k|}
_Z8HexDigitc:
   64|  8.17M|{
   65|  8.17M|    return p_util_hexdigit[(unsigned char)c];
   66|  8.17M|}

_ZN11ECC_ContextD2Ev:
  482|      2|{
  483|      2|    ECC_Stop();
  484|      2|}
key.cpp:_ZL8ECC_Stopv:
  467|      2|static void ECC_Stop() {
  468|      2|    secp256k1_context *ctx = secp256k1_context_sign;
  469|      2|    secp256k1_context_sign = nullptr;
  470|       |
  471|      2|    if (ctx) {
  ------------------
  |  Branch (471:9): [True: 2, False: 0]
  ------------------
  472|      2|        secp256k1_context_destroy(ctx);
  473|      2|    }
  474|      2|}

_ZN9prevectorILj28EhjiE3endEv:
  304|  19.2k|    iterator end() { return iterator(item_ptr(size())); }
_ZN9prevectorILj28EhjiE8item_ptrEi:
  206|  83.6k|    T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
  ------------------
  |  Branch (206:47): [True: 83.6k, False: 0]
  ------------------
_ZNK9prevectorILj28EhjiE9is_directEv:
  173|   308k|    bool is_direct() const { return _size <= N; }
_ZN9prevectorILj28EhjiE10direct_ptrEi:
  169|  83.6k|    T* direct_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.direct) + pos; }
_ZN9prevectorILj28EhjiE6insertENS0_8iteratorERKh:
  359|  9.64k|    iterator insert(iterator pos, const T& value) {
  360|  9.64k|        size_type p = pos - begin();
  361|  9.64k|        size_type new_size = size() + 1;
  362|  9.64k|        if (capacity() < new_size) {
  ------------------
  |  Branch (362:13): [True: 0, False: 9.64k]
  ------------------
  363|      0|            change_capacity(new_size + (new_size >> 1));
  364|      0|        }
  365|  9.64k|        T* ptr = item_ptr(p);
  366|  9.64k|        T* dst = ptr + 1;
  367|  9.64k|        memmove(dst, ptr, (size() - p) * sizeof(T));
  368|  9.64k|        _size++;
  369|  9.64k|        new(static_cast<void*>(ptr)) T(value);
  370|  9.64k|        return iterator(ptr);
  371|  9.64k|    }
_ZN9prevectorILj28EhjiE5beginEv:
  302|  19.2k|    iterator begin() { return iterator(item_ptr(0)); }
_ZmiN9prevectorILj28EhjiE8iteratorES1_:
   66|  19.2k|        difference_type friend operator-(iterator a, iterator b) { return (&(*a) - &(*b)); }
_ZNK9prevectorILj28EhjiE8iteratordeEv:
   59|  38.5k|        T& operator*() const { return *ptr; }
_ZNK9prevectorILj28EhjiE8capacityEv:
  312|  45.0k|    size_t capacity() const {
  313|  45.0k|        if (is_direct()) {
  ------------------
  |  Branch (313:13): [True: 45.0k, False: 0]
  ------------------
  314|  45.0k|            return N;
  315|  45.0k|        } else {
  316|      0|            return _union.indirect_contents.capacity;
  317|      0|        }
  318|  45.0k|    }
_ZN9prevectorILj28EhjiE6insertITkNSt3__114input_iteratorENS2_11__wrap_iterIPKhEEEEvNS0_8iteratorET_S8_:
  387|  9.64k|    void insert(iterator pos, InputIterator first, InputIterator last) {
  388|  9.64k|        size_type p = pos - begin();
  389|  9.64k|        difference_type count = last - first;
  390|  9.64k|        size_type new_size = size() + count;
  391|  9.64k|        if (capacity() < new_size) {
  ------------------
  |  Branch (391:13): [True: 0, False: 9.64k]
  ------------------
  392|      0|            change_capacity(new_size + (new_size >> 1));
  393|      0|        }
  394|  9.64k|        T* ptr = item_ptr(p);
  395|  9.64k|        T* dst = ptr + count;
  396|  9.64k|        memmove(dst, ptr, (size() - p) * sizeof(T));
  397|  9.64k|        _size += count;
  398|  9.64k|        fill(ptr, first, last);
  399|  9.64k|    }
_ZN9prevectorILj28EhjiE4fillITkNSt3__114input_iteratorENS2_11__wrap_iterIPKhEEEEvPhT_S8_:
  214|  9.64k|    void fill(T* dst, InputIterator first, InputIterator last) {
  215|  40.4k|        while (first != last) {
  ------------------
  |  Branch (215:16): [True: 30.8k, False: 9.64k]
  ------------------
  216|  30.8k|            new(static_cast<void*>(dst)) T(*first);
  217|  30.8k|            ++dst;
  218|  30.8k|            ++first;
  219|  30.8k|        }
  220|  9.64k|    }
_ZN9prevectorILj28EhjiE9push_backERKh:
  444|  25.7k|    void push_back(const T& value) {
  445|  25.7k|        emplace_back(value);
  446|  25.7k|    }
_ZN9prevectorILj28EhjiE12emplace_backIJRKhEEEvDpOT_:
  435|  25.7k|    void emplace_back(Args&&... args) {
  436|  25.7k|        size_type new_size = size() + 1;
  437|  25.7k|        if (capacity() < new_size) {
  ------------------
  |  Branch (437:13): [True: 0, False: 25.7k]
  ------------------
  438|      0|            change_capacity(new_size + (new_size >> 1));
  439|      0|        }
  440|  25.7k|        new(item_ptr(size())) T(std::forward<Args>(args)...);
  441|  25.7k|        _size++;
  442|  25.7k|    }
_ZNK9prevectorILj28EhjiE4sizeEv:
  294|   144k|    size_type size() const {
  295|   144k|        return is_direct() ? _size : _size - N - 1;
  ------------------
  |  Branch (295:16): [True: 144k, False: 0]
  ------------------
  296|   144k|    }
_ZN9prevectorILj28EhjiED2Ev:
  474|  35.4k|    ~prevector() {
  475|  35.4k|        if (!is_direct()) {
  ------------------
  |  Branch (475:13): [True: 0, False: 35.4k]
  ------------------
  476|      0|            free(_union.indirect_contents.indirect);
  477|      0|            _union.indirect_contents.indirect = nullptr;
  478|      0|        }
  479|  35.4k|    }
_ZN9prevectorILj28EhjiEC2Ev:
  243|  35.4k|    prevector() = default;
_ZN9prevectorILj28EhjiE8iteratorC2EPh:
   58|  48.2k|        iterator(T* ptr_) : ptr(ptr_) {}

_ZN7CPubKey6GetLenEh:
   61|  1.24M|    {
   62|  1.24M|        if (chHeader == 2 || chHeader == 3)
  ------------------
  |  Branch (62:13): [True: 611k, False: 636k]
  |  Branch (62:30): [True: 636k, False: 0]
  ------------------
   63|  1.24M|            return COMPRESSED_SIZE;
   64|      0|        if (chHeader == 4 || chHeader == 6 || chHeader == 7)
  ------------------
  |  Branch (64:13): [True: 0, False: 0]
  |  Branch (64:30): [True: 0, False: 0]
  |  Branch (64:47): [True: 0, False: 0]
  ------------------
   65|      0|            return SIZE;
   66|      0|        return 0;
   67|      0|    }
_ZNK7CPubKey4sizeEv:
  112|  1.24M|    unsigned int size() const { return GetLen(vch[0]); }
_ZltRK7CPubKeyS1_:
  129|  1.44M|    {
  130|  1.44M|        return a.vch[0] < b.vch[0] ||
  ------------------
  |  Branch (130:16): [True: 98.7k, False: 1.34M]
  ------------------
  131|  1.44M|               (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
  ------------------
  |  Branch (131:17): [True: 1.24M, False: 99.8k]
  |  Branch (131:41): [True: 401k, False: 846k]
  ------------------
  132|  1.44M|    }

_ZN10miniscript8internal12SanitizeTypeENS_4TypeE:
   19|  43.0M|Type SanitizeType(Type e) {
   20|  43.0M|    int num_types = (e << "K"_mst) + (e << "V"_mst) + (e << "B"_mst) + (e << "W"_mst);
   21|  43.0M|    if (num_types == 0) return ""_mst; // No valid type, don't care about the rest
  ------------------
  |  Branch (21:9): [True: 26.1M, False: 16.9M]
  ------------------
   22|  16.9M|    assert(num_types == 1); // K, V, B, W all conflict with each other
   23|  16.9M|    assert(!(e << "z"_mst) || !(e << "o"_mst)); // z conflicts with o
   24|  16.9M|    assert(!(e << "n"_mst) || !(e << "z"_mst)); // n conflicts with z
   25|  16.9M|    assert(!(e << "n"_mst) || !(e << "W"_mst)); // n conflicts with W
   26|  16.9M|    assert(!(e << "V"_mst) || !(e << "d"_mst)); // V conflicts with d
   27|  16.9M|    assert(!(e << "K"_mst) ||  (e << "u"_mst)); // K implies u
   28|  16.9M|    assert(!(e << "V"_mst) || !(e << "u"_mst)); // V conflicts with u
   29|  16.9M|    assert(!(e << "e"_mst) || !(e << "f"_mst)); // e conflicts with f
   30|  16.9M|    assert(!(e << "e"_mst) ||  (e << "d"_mst)); // e implies d
   31|  16.9M|    assert(!(e << "V"_mst) || !(e << "e"_mst)); // V conflicts with e
   32|  16.9M|    assert(!(e << "d"_mst) || !(e << "f"_mst)); // d conflicts with f
   33|  16.9M|    assert(!(e << "V"_mst) ||  (e << "f"_mst)); // V implies f
   34|  16.9M|    assert(!(e << "K"_mst) ||  (e << "s"_mst)); // K implies s
   35|  16.9M|    assert(!(e << "z"_mst) ||  (e << "m"_mst)); // z implies m
   36|  16.9M|    return e;
   37|  16.9M|}
_ZN10miniscript8internal11ComputeTypeENS_8FragmentENS_4TypeES2_S2_RKNSt3__16vectorIS2_NS3_9allocatorIS2_EEEEjmmmNS_17MiniscriptContextE:
   40|  43.0M|                 size_t data_size, size_t n_subs, size_t n_keys, MiniscriptContext ms_ctx) {
   41|       |    // Sanity check on data
   42|  43.0M|    if (fragment == Fragment::SHA256 || fragment == Fragment::HASH256) {
  ------------------
  |  Branch (42:9): [True: 261, False: 43.0M]
  |  Branch (42:41): [True: 211, False: 43.0M]
  ------------------
   43|    472|        assert(data_size == 32);
   44|  43.0M|    } else if (fragment == Fragment::RIPEMD160 || fragment == Fragment::HASH160) {
  ------------------
  |  Branch (44:16): [True: 856, False: 43.0M]
  |  Branch (44:51): [True: 689, False: 43.0M]
  ------------------
   45|  1.54k|        assert(data_size == 20);
   46|  43.0M|    } else {
   47|  43.0M|        assert(data_size == 0);
   48|  43.0M|    }
   49|       |    // Sanity check on k
   50|  43.0M|    if (fragment == Fragment::OLDER || fragment == Fragment::AFTER) {
  ------------------
  |  Branch (50:9): [True: 9.82k, False: 43.0M]
  |  Branch (50:40): [True: 4.75k, False: 43.0M]
  ------------------
   51|  14.5k|        assert(k >= 1 && k < 0x80000000UL);
   52|  43.0M|    } else if (fragment == Fragment::MULTI || fragment == Fragment::MULTI_A) {
  ------------------
  |  Branch (52:16): [True: 2.77k, False: 43.0M]
  |  Branch (52:47): [True: 4.39k, False: 43.0M]
  ------------------
   53|  7.16k|        assert(k >= 1 && k <= n_keys);
   54|  43.0M|    } else if (fragment == Fragment::THRESH) {
  ------------------
  |  Branch (54:16): [True: 6.50k, False: 43.0M]
  ------------------
   55|  6.50k|        assert(k >= 1 && k <= n_subs);
   56|  43.0M|    } else {
   57|  43.0M|        assert(k == 0);
   58|  43.0M|    }
   59|       |    // Sanity check on subs
   60|  43.0M|    if (fragment == Fragment::AND_V || fragment == Fragment::AND_B || fragment == Fragment::OR_B ||
  ------------------
  |  Branch (60:9): [True: 8.55M, False: 34.4M]
  |  Branch (60:40): [True: 13.4k, False: 34.4M]
  |  Branch (60:71): [True: 4.79k, False: 34.4M]
  ------------------
   61|  43.0M|        fragment == Fragment::OR_C || fragment == Fragment::OR_I || fragment == Fragment::OR_D) {
  ------------------
  |  Branch (61:9): [True: 3.65k, False: 34.4M]
  |  Branch (61:39): [True: 7.66M, False: 26.7M]
  |  Branch (61:69): [True: 5.69k, False: 26.7M]
  ------------------
   62|  16.2M|        assert(n_subs == 2);
   63|  26.7M|    } else if (fragment == Fragment::ANDOR) {
  ------------------
  |  Branch (63:16): [True: 8.99k, False: 26.7M]
  ------------------
   64|  8.99k|        assert(n_subs == 3);
   65|  26.7M|    } else if (fragment == Fragment::WRAP_A || fragment == Fragment::WRAP_S || fragment == Fragment::WRAP_C ||
  ------------------
  |  Branch (65:16): [True: 299k, False: 26.4M]
  |  Branch (65:48): [True: 149k, False: 26.3M]
  |  Branch (65:80): [True: 9.17M, False: 17.1M]
  ------------------
   66|  26.7M|               fragment == Fragment::WRAP_D || fragment == Fragment::WRAP_V || fragment == Fragment::WRAP_J ||
  ------------------
  |  Branch (66:16): [True: 185k, False: 16.9M]
  |  Branch (66:48): [True: 83.0k, False: 16.8M]
  |  Branch (66:80): [True: 112k, False: 16.7M]
  ------------------
   67|  26.7M|               fragment == Fragment::WRAP_N) {
  ------------------
  |  Branch (67:16): [True: 359k, False: 16.4M]
  ------------------
   68|  10.3M|        assert(n_subs == 1);
   69|  16.4M|    } else if (fragment != Fragment::THRESH) {
  ------------------
  |  Branch (69:16): [True: 16.4M, False: 6.50k]
  ------------------
   70|  16.4M|        assert(n_subs == 0);
   71|  16.4M|    }
   72|       |    // Sanity check on keys
   73|  43.0M|    if (fragment == Fragment::PK_K || fragment == Fragment::PK_H) {
  ------------------
  |  Branch (73:9): [True: 18.8k, False: 43.0M]
  |  Branch (73:39): [True: 18.4k, False: 42.9M]
  ------------------
   74|  37.3k|        assert(n_keys == 1);
   75|  42.9M|    } else if (fragment == Fragment::MULTI) {
  ------------------
  |  Branch (75:16): [True: 2.77k, False: 42.9M]
  ------------------
   76|  2.77k|        assert(n_keys >= 1 && n_keys <= MAX_PUBKEYS_PER_MULTISIG);
   77|  2.77k|        assert(!IsTapscript(ms_ctx));
   78|  42.9M|    } else if (fragment == Fragment::MULTI_A) {
  ------------------
  |  Branch (78:16): [True: 4.39k, False: 42.9M]
  ------------------
   79|  4.39k|        assert(n_keys >= 1 && n_keys <= MAX_PUBKEYS_PER_MULTI_A);
   80|  4.39k|        assert(IsTapscript(ms_ctx));
   81|  42.9M|    } else {
   82|  42.9M|        assert(n_keys == 0);
   83|  42.9M|    }
   84|       |
   85|       |    // Below is the per-fragment logic for computing the expression types.
   86|       |    // It heavily relies on Type's << operator (where "X << a_mst" means
   87|       |    // "X has all properties listed in a").
   88|  43.0M|    switch (fragment) {
  ------------------
  |  Branch (88:13): [True: 0, False: 43.0M]
  ------------------
   89|  18.8k|        case Fragment::PK_K: return "Konudemsxk"_mst;
  ------------------
  |  Branch (89:9): [True: 18.8k, False: 43.0M]
  ------------------
   90|  18.4k|        case Fragment::PK_H: return "Knudemsxk"_mst;
  ------------------
  |  Branch (90:9): [True: 18.4k, False: 43.0M]
  ------------------
   91|  9.82k|        case Fragment::OLDER: return
  ------------------
  |  Branch (91:9): [True: 9.82k, False: 43.0M]
  ------------------
   92|  9.82k|            "g"_mst.If(k & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) |
   93|  9.82k|            "h"_mst.If(!(k & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG)) |
   94|  9.82k|            "Bzfmxk"_mst;
   95|  4.75k|        case Fragment::AFTER: return
  ------------------
  |  Branch (95:9): [True: 4.75k, False: 43.0M]
  ------------------
   96|  4.75k|            "i"_mst.If(k >= LOCKTIME_THRESHOLD) |
   97|  4.75k|            "j"_mst.If(k < LOCKTIME_THRESHOLD) |
   98|  4.75k|            "Bzfmxk"_mst;
   99|    261|        case Fragment::SHA256: return "Bonudmk"_mst;
  ------------------
  |  Branch (99:9): [True: 261, False: 43.0M]
  ------------------
  100|    856|        case Fragment::RIPEMD160: return "Bonudmk"_mst;
  ------------------
  |  Branch (100:9): [True: 856, False: 43.0M]
  ------------------
  101|    211|        case Fragment::HASH256: return "Bonudmk"_mst;
  ------------------
  |  Branch (101:9): [True: 211, False: 43.0M]
  ------------------
  102|    689|        case Fragment::HASH160: return "Bonudmk"_mst;
  ------------------
  |  Branch (102:9): [True: 689, False: 43.0M]
  ------------------
  103|  8.60M|        case Fragment::JUST_1: return "Bzufmxk"_mst;
  ------------------
  |  Branch (103:9): [True: 8.60M, False: 34.4M]
  ------------------
  104|  7.73M|        case Fragment::JUST_0: return "Bzudemsxk"_mst;
  ------------------
  |  Branch (104:9): [True: 7.73M, False: 35.2M]
  ------------------
  105|   299k|        case Fragment::WRAP_A: return
  ------------------
  |  Branch (105:9): [True: 299k, False: 42.7M]
  ------------------
  106|   299k|            "W"_mst.If(x << "B"_mst) | // W=B_x
  107|   299k|            (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x
  108|   299k|            (x & "udfems"_mst) | // u=u_x, d=d_x, f=f_x, e=e_x, m=m_x, s=s_x
  109|   299k|            "x"_mst; // x
  110|   149k|        case Fragment::WRAP_S: return
  ------------------
  |  Branch (110:9): [True: 149k, False: 42.8M]
  ------------------
  111|   149k|            "W"_mst.If(x << "Bo"_mst) | // W=B_x*o_x
  112|   149k|            (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x
  113|   149k|            (x & "udfemsx"_mst); // u=u_x, d=d_x, f=f_x, e=e_x, m=m_x, s=s_x, x=x_x
  114|  9.17M|        case Fragment::WRAP_C: return
  ------------------
  |  Branch (114:9): [True: 9.17M, False: 33.8M]
  ------------------
  115|  9.17M|            "B"_mst.If(x << "K"_mst) | // B=K_x
  116|  9.17M|            (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x
  117|  9.17M|            (x & "ondfem"_mst) | // o=o_x, n=n_x, d=d_x, f=f_x, e=e_x, m=m_x
  118|  9.17M|            "us"_mst; // u, s
  119|   185k|        case Fragment::WRAP_D: return
  ------------------
  |  Branch (119:9): [True: 185k, False: 42.8M]
  ------------------
  120|   185k|            "B"_mst.If(x << "Vz"_mst) | // B=V_x*z_x
  121|   185k|            "o"_mst.If(x << "z"_mst) | // o=z_x
  122|   185k|            "e"_mst.If(x << "f"_mst) | // e=f_x
  123|   185k|            (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x
  124|   185k|            (x & "ms"_mst) | // m=m_x, s=s_x
  125|       |            // NOTE: 'd:' is 'u' under Tapscript but not P2WSH as MINIMALIF is only a policy rule there.
  126|   185k|            "u"_mst.If(IsTapscript(ms_ctx)) |
  127|   185k|            "ndx"_mst; // n, d, x
  128|  83.0k|        case Fragment::WRAP_V: return
  ------------------
  |  Branch (128:9): [True: 83.0k, False: 42.9M]
  ------------------
  129|  83.0k|            "V"_mst.If(x << "B"_mst) | // V=B_x
  130|  83.0k|            (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x
  131|  83.0k|            (x & "zonms"_mst) | // z=z_x, o=o_x, n=n_x, m=m_x, s=s_x
  132|  83.0k|            "fx"_mst; // f, x
  133|   112k|        case Fragment::WRAP_J: return
  ------------------
  |  Branch (133:9): [True: 112k, False: 42.9M]
  ------------------
  134|   112k|            "B"_mst.If(x << "Bn"_mst) | // B=B_x*n_x
  135|   112k|            "e"_mst.If(x << "f"_mst) | // e=f_x
  136|   112k|            (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x
  137|   112k|            (x & "oums"_mst) | // o=o_x, u=u_x, m=m_x, s=s_x
  138|   112k|            "ndx"_mst; // n, d, x
  139|   359k|        case Fragment::WRAP_N: return
  ------------------
  |  Branch (139:9): [True: 359k, False: 42.6M]
  ------------------
  140|   359k|            (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x
  141|   359k|            (x & "Bzondfems"_mst) | // B=B_x, z=z_x, o=o_x, n=n_x, d=d_x, f=f_x, e=e_x, m=m_x, s=s_x
  142|   359k|            "ux"_mst; // u, x
  143|  8.55M|        case Fragment::AND_V: return
  ------------------
  |  Branch (143:9): [True: 8.55M, False: 34.4M]
  ------------------
  144|  8.55M|            (y & "KVB"_mst).If(x << "V"_mst) | // B=V_x*B_y, V=V_x*V_y, K=V_x*K_y
  145|  8.55M|            (x & "n"_mst) | (y & "n"_mst).If(x << "z"_mst) | // n=n_x+z_x*n_y
  146|  8.55M|            ((x | y) & "o"_mst).If((x | y) << "z"_mst) | // o=o_x*z_y+z_x*o_y
  147|  8.55M|            (x & y & "dmz"_mst) | // d=d_x*d_y, m=m_x*m_y, z=z_x*z_y
  148|  8.55M|            ((x | y) & "s"_mst) | // s=s_x+s_y
  149|  8.55M|            "f"_mst.If((y << "f"_mst) || (x << "s"_mst)) | // f=f_y+s_x
  ------------------
  |  Branch (149:24): [True: 8.54M, False: 1.23k]
  |  Branch (149:42): [True: 162, False: 1.07k]
  ------------------
  150|  8.55M|            (y & "ux"_mst) | // u=u_y, x=x_y
  151|  8.55M|            ((x | y) & "ghij"_mst) | // g=g_x+g_y, h=h_x+h_y, i=i_x+i_y, j=j_x+j_y
  152|  8.55M|            "k"_mst.If(((x & y) << "k"_mst) &&
  ------------------
  |  Branch (152:24): [True: 14.5k, False: 8.53M]
  ------------------
  153|  8.55M|                !(((x << "g"_mst) && (y << "h"_mst)) ||
  ------------------
  |  Branch (153:20): [True: 398, False: 14.1k]
  |  Branch (153:38): [True: 197, False: 201]
  ------------------
  154|  14.5k|                ((x << "h"_mst) && (y << "g"_mst)) ||
  ------------------
  |  Branch (154:18): [True: 503, False: 13.8k]
  |  Branch (154:36): [True: 162, False: 341]
  ------------------
  155|  14.5k|                ((x << "i"_mst) && (y << "j"_mst)) ||
  ------------------
  |  Branch (155:18): [True: 472, False: 13.7k]
  |  Branch (155:36): [True: 277, False: 195]
  ------------------
  156|  14.5k|                ((x << "j"_mst) && (y << "i"_mst)))); // k=k_x*k_y*!(g_x*h_y + h_x*g_y + i_x*j_y + j_x*i_y)
  ------------------
  |  Branch (156:18): [True: 933, False: 12.9k]
  |  Branch (156:36): [True: 3, False: 930]
  ------------------
  157|  13.4k|        case Fragment::AND_B: return
  ------------------
  |  Branch (157:9): [True: 13.4k, False: 43.0M]
  ------------------
  158|  13.4k|            (x & "B"_mst).If(y << "W"_mst) | // B=B_x*W_y
  159|  13.4k|            ((x | y) & "o"_mst).If((x | y) << "z"_mst) | // o=o_x*z_y+z_x*o_y
  160|  13.4k|            (x & "n"_mst) | (y & "n"_mst).If(x << "z"_mst) | // n=n_x+z_x*n_y
  161|  13.4k|            (x & y & "e"_mst).If((x & y) << "s"_mst) | // e=e_x*e_y*s_x*s_y
  162|  13.4k|            (x & y & "dzm"_mst) | // d=d_x*d_y, z=z_x*z_y, m=m_x*m_y
  163|  13.4k|            "f"_mst.If(((x & y) << "f"_mst) || (x << "sf"_mst) || (y << "sf"_mst)) | // f=f_x*f_y + f_x*s_x + f_y*s_y
  ------------------
  |  Branch (163:24): [True: 600, False: 12.8k]
  |  Branch (163:48): [True: 384, False: 12.4k]
  |  Branch (163:67): [True: 2, False: 12.4k]
  ------------------
  164|  13.4k|            ((x | y) & "s"_mst) | // s=s_x+s_y
  165|  13.4k|            "ux"_mst | // u, x
  166|  13.4k|            ((x | y) & "ghij"_mst) | // g=g_x+g_y, h=h_x+h_y, i=i_x+i_y, j=j_x+j_y
  167|  13.4k|            "k"_mst.If(((x & y) << "k"_mst) &&
  ------------------
  |  Branch (167:24): [True: 1.90k, False: 11.5k]
  ------------------
  168|  13.4k|                !(((x << "g"_mst) && (y << "h"_mst)) ||
  ------------------
  |  Branch (168:20): [True: 285, False: 1.62k]
  |  Branch (168:38): [True: 87, False: 198]
  ------------------
  169|  1.90k|                ((x << "h"_mst) && (y << "g"_mst)) ||
  ------------------
  |  Branch (169:18): [True: 480, False: 1.34k]
  |  Branch (169:36): [True: 70, False: 410]
  ------------------
  170|  1.90k|                ((x << "i"_mst) && (y << "j"_mst)) ||
  ------------------
  |  Branch (170:18): [True: 270, False: 1.48k]
  |  Branch (170:36): [True: 66, False: 204]
  ------------------
  171|  1.90k|                ((x << "j"_mst) && (y << "i"_mst)))); // k=k_x*k_y*!(g_x*h_y + h_x*g_y + i_x*j_y + j_x*i_y)
  ------------------
  |  Branch (171:18): [True: 449, False: 1.23k]
  |  Branch (171:36): [True: 2, False: 447]
  ------------------
  172|  4.79k|        case Fragment::OR_B: return
  ------------------
  |  Branch (172:9): [True: 4.79k, False: 43.0M]
  ------------------
  173|  4.79k|            "B"_mst.If(x << "Bd"_mst && y << "Wd"_mst) | // B=B_x*d_x*W_x*d_y
  ------------------
  |  Branch (173:24): [True: 2.24k, False: 2.54k]
  |  Branch (173:41): [True: 563, False: 1.68k]
  ------------------
  174|  4.79k|            ((x | y) & "o"_mst).If((x | y) << "z"_mst) | // o=o_x*z_y+z_x*o_y
  175|  4.79k|            (x & y & "m"_mst).If((x | y) << "s"_mst && (x & y) << "e"_mst) | // m=m_x*m_y*e_x*e_y*(s_x+s_y)
  ------------------
  |  Branch (175:34): [True: 3.59k, False: 1.20k]
  |  Branch (175:56): [True: 1.10k, False: 2.48k]
  ------------------
  176|  4.79k|            (x & y & "zse"_mst) | // z=z_x*z_y, s=s_x*s_y, e=e_x*e_y
  177|  4.79k|            "dux"_mst | // d, u, x
  178|  4.79k|            ((x | y) & "ghij"_mst) | // g=g_x+g_y, h=h_x+h_y, i=i_x+i_y, j=j_x+j_y
  179|  4.79k|            (x & y & "k"_mst); // k=k_x*k_y
  180|  5.69k|        case Fragment::OR_D: return
  ------------------
  |  Branch (180:9): [True: 5.69k, False: 43.0M]
  ------------------
  181|  5.69k|            (y & "B"_mst).If(x << "Bdu"_mst) | // B=B_y*B_x*d_x*u_x
  182|  5.69k|            (x & "o"_mst).If(y << "z"_mst) | // o=o_x*z_y
  183|  5.69k|            (x & y & "m"_mst).If(x << "e"_mst && (x | y) << "s"_mst) | // m=m_x*m_y*e_x*(s_x+s_y)
  ------------------
  |  Branch (183:34): [True: 3.15k, False: 2.53k]
  |  Branch (183:50): [True: 1.56k, False: 1.59k]
  ------------------
  184|  5.69k|            (x & y & "zs"_mst) | // z=z_x*z_y, s=s_x*s_y
  185|  5.69k|            (y & "ufde"_mst) | // u=u_y, f=f_y, d=d_y, e=e_y
  186|  5.69k|            "x"_mst | // x
  187|  5.69k|            ((x | y) & "ghij"_mst) | // g=g_x+g_y, h=h_x+h_y, i=i_x+i_y, j=j_x+j_y
  188|  5.69k|            (x & y & "k"_mst); // k=k_x*k_y
  189|  3.65k|        case Fragment::OR_C: return
  ------------------
  |  Branch (189:9): [True: 3.65k, False: 43.0M]
  ------------------
  190|  3.65k|            (y & "V"_mst).If(x << "Bdu"_mst) | // V=V_y*B_x*u_x*d_x
  191|  3.65k|            (x & "o"_mst).If(y << "z"_mst) | // o=o_x*z_y
  192|  3.65k|            (x & y & "m"_mst).If(x << "e"_mst && (x | y) << "s"_mst) | // m=m_x*m_y*e_x*(s_x+s_y)
  ------------------
  |  Branch (192:34): [True: 2.16k, False: 1.49k]
  |  Branch (192:50): [True: 1.42k, False: 742]
  ------------------
  193|  3.65k|            (x & y & "zs"_mst) | // z=z_x*z_y, s=s_x*s_y
  194|  3.65k|            "fx"_mst | // f, x
  195|  3.65k|            ((x | y) & "ghij"_mst) | // g=g_x+g_y, h=h_x+h_y, i=i_x+i_y, j=j_x+j_y
  196|  3.65k|            (x & y & "k"_mst); // k=k_x*k_y
  197|  7.66M|        case Fragment::OR_I: return
  ------------------
  |  Branch (197:9): [True: 7.66M, False: 35.3M]
  ------------------
  198|  7.66M|            (x & y & "VBKufs"_mst) | // V=V_x*V_y, B=B_x*B_y, K=K_x*K_y, u=u_x*u_y, f=f_x*f_y, s=s_x*s_y
  199|  7.66M|            "o"_mst.If((x & y) << "z"_mst) | // o=z_x*z_y
  200|  7.66M|            ((x | y) & "e"_mst).If((x | y) << "f"_mst) | // e=e_x*f_y+f_x*e_y
  201|  7.66M|            (x & y & "m"_mst).If((x | y) << "s"_mst) | // m=m_x*m_y*(s_x+s_y)
  202|  7.66M|            ((x | y) & "d"_mst) | // d=d_x+d_y
  203|  7.66M|            "x"_mst | // x
  204|  7.66M|            ((x | y) & "ghij"_mst) | // g=g_x+g_y, h=h_x+h_y, i=i_x+i_y, j=j_x+j_y
  205|  7.66M|            (x & y & "k"_mst); // k=k_x*k_y
  206|  8.99k|        case Fragment::ANDOR: return
  ------------------
  |  Branch (206:9): [True: 8.99k, False: 43.0M]
  ------------------
  207|  8.99k|            (y & z & "BKV"_mst).If(x << "Bdu"_mst) | // B=B_x*d_x*u_x*B_y*B_z, K=B_x*d_x*u_x*K_y*K_z, V=B_x*d_x*u_x*V_y*V_z
  208|  8.99k|            (x & y & z & "z"_mst) | // z=z_x*z_y*z_z
  209|  8.99k|            ((x | (y & z)) & "o"_mst).If((x | (y & z)) << "z"_mst) | // o=o_x*z_y*z_z+z_x*o_y*o_z
  210|  8.99k|            (y & z & "u"_mst) | // u=u_y*u_z
  211|  8.99k|            (z & "f"_mst).If((x << "s"_mst) || (y << "f"_mst)) | // f=(s_x+f_y)*f_z
  ------------------
  |  Branch (211:30): [True: 5.30k, False: 3.69k]
  |  Branch (211:48): [True: 1.48k, False: 2.20k]
  ------------------
  212|  8.99k|            (z & "d"_mst) | // d=d_z
  213|  8.99k|            (z & "e"_mst).If(x << "s"_mst || y << "f"_mst) | // e=e_z*(s_x+f_y)
  ------------------
  |  Branch (213:30): [True: 5.30k, False: 3.69k]
  |  Branch (213:46): [True: 1.48k, False: 2.20k]
  ------------------
  214|  8.99k|            (x & y & z & "m"_mst).If(x << "e"_mst && (x | y | z) << "s"_mst) | // m=m_x*m_y*m_z*e_x*(s_x+s_y+s_z)
  ------------------
  |  Branch (214:38): [True: 5.44k, False: 3.54k]
  |  Branch (214:54): [True: 5.25k, False: 188]
  ------------------
  215|  8.99k|            (z & (x | y) & "s"_mst) | // s=s_z*(s_x+s_y)
  216|  8.99k|            "x"_mst | // x
  217|  8.99k|            ((x | y | z) & "ghij"_mst) | // g=g_x+g_y+g_z, h=h_x+h_y+h_z, i=i_x+i_y+i_z, j=j_x+j_y_j_z
  218|  8.99k|            "k"_mst.If(((x & y & z) << "k"_mst) &&
  ------------------
  |  Branch (218:24): [True: 6.19k, False: 2.79k]
  ------------------
  219|  8.99k|                !(((x << "g"_mst) && (y << "h"_mst)) ||
  ------------------
  |  Branch (219:20): [True: 280, False: 5.91k]
  |  Branch (219:38): [True: 66, False: 214]
  ------------------
  220|  6.19k|                ((x << "h"_mst) && (y << "g"_mst)) ||
  ------------------
  |  Branch (220:18): [True: 630, False: 5.49k]
  |  Branch (220:36): [True: 68, False: 562]
  ------------------
  221|  6.19k|                ((x << "i"_mst) && (y << "j"_mst)) ||
  ------------------
  |  Branch (221:18): [True: 262, False: 5.79k]
  |  Branch (221:36): [True: 66, False: 196]
  ------------------
  222|  6.19k|                ((x << "j"_mst) && (y << "i"_mst)))); // k=k_x*k_y*k_z* !(g_x*h_y + h_x*g_y + i_x*j_y + j_x*i_y)
  ------------------
  |  Branch (222:18): [True: 196, False: 5.79k]
  |  Branch (222:36): [True: 0, False: 196]
  ------------------
  223|  2.77k|        case Fragment::MULTI: {
  ------------------
  |  Branch (223:9): [True: 2.77k, False: 43.0M]
  ------------------
  224|  2.77k|            return "Bnudemsk"_mst;
  225|      0|        }
  226|  4.39k|        case Fragment::MULTI_A: {
  ------------------
  |  Branch (226:9): [True: 4.39k, False: 43.0M]
  ------------------
  227|  4.39k|            return "Budemsk"_mst;
  228|      0|        }
  229|  6.50k|        case Fragment::THRESH: {
  ------------------
  |  Branch (229:9): [True: 6.50k, False: 43.0M]
  ------------------
  230|  6.50k|            bool all_e = true;
  231|  6.50k|            bool all_m = true;
  232|  6.50k|            uint32_t args = 0;
  233|  6.50k|            uint32_t num_s = 0;
  234|  6.50k|            Type acc_tl = "k"_mst;
  235|  15.7k|            for (size_t i = 0; i < sub_types.size(); ++i) {
  ------------------
  |  Branch (235:32): [True: 12.7k, False: 3.05k]
  ------------------
  236|  12.7k|                Type t = sub_types[i];
  237|  12.7k|                static constexpr auto WDU{"Wdu"_mst}, BDU{"Bdu"_mst};
  238|  12.7k|                if (!(t << (i ? WDU : BDU))) return ""_mst; // Require Bdu, Wdu, Wdu, ...
  ------------------
  |  Branch (238:21): [True: 3.44k, False: 9.25k]
  |  Branch (238:29): [True: 6.19k, False: 6.50k]
  ------------------
  239|  9.25k|                if (!(t << "e"_mst)) all_e = false;
  ------------------
  |  Branch (239:21): [True: 1.61k, False: 7.63k]
  ------------------
  240|  9.25k|                if (!(t << "m"_mst)) all_m = false;
  ------------------
  |  Branch (240:21): [True: 1.07k, False: 8.17k]
  ------------------
  241|  9.25k|                if (t << "s"_mst) num_s += 1;
  ------------------
  |  Branch (241:21): [True: 5.56k, False: 3.68k]
  ------------------
  242|  9.25k|                args += (t << "z"_mst) ? 0 : (t << "o"_mst) ? 1 : 2;
  ------------------
  |  Branch (242:25): [True: 2.15k, False: 7.09k]
  |  Branch (242:46): [True: 1.73k, False: 5.35k]
  ------------------
  243|  9.25k|                acc_tl = ((acc_tl | t) & "ghij"_mst) |
  244|       |                    // Thresh contains a combination of timelocks if it has threshold > 1 and
  245|       |                    // it contains two different children that have different types of timelocks
  246|       |                    // Note how if any of the children don't have "k", the parent also does not have "k"
  247|  9.25k|                    "k"_mst.If(((acc_tl & t) << "k"_mst) && ((k <= 1) ||
  ------------------
  |  Branch (247:32): [True: 8.98k, False: 271]
  |  Branch (247:62): [True: 4.09k, False: 4.88k]
  ------------------
  248|  8.98k|                        ((k > 1) && !(((acc_tl << "g"_mst) && (t << "h"_mst)) ||
  ------------------
  |  Branch (248:26): [True: 4.88k, False: 0]
  |  Branch (248:40): [True: 691, False: 4.19k]
  |  Branch (248:63): [True: 115, False: 576]
  ------------------
  249|  4.88k|                        ((acc_tl << "h"_mst) && (t << "g"_mst)) ||
  ------------------
  |  Branch (249:26): [True: 697, False: 4.07k]
  |  Branch (249:49): [True: 197, False: 500]
  ------------------
  250|  4.88k|                        ((acc_tl << "i"_mst) && (t << "j"_mst)) ||
  ------------------
  |  Branch (250:26): [True: 307, False: 4.26k]
  |  Branch (250:49): [True: 70, False: 237]
  ------------------
  251|  4.88k|                        ((acc_tl << "j"_mst) && (t << "i"_mst))))));
  ------------------
  |  Branch (251:26): [True: 506, False: 3.99k]
  |  Branch (251:49): [True: 0, False: 506]
  ------------------
  252|  9.25k|            }
  253|  3.05k|            return "Bdu"_mst |
  254|  3.05k|                   "z"_mst.If(args == 0) | // z=all z
  255|  3.05k|                   "o"_mst.If(args == 1) | // o=all z except one o
  256|  3.05k|                   "e"_mst.If(all_e && num_s == n_subs) | // e=all e and all s
  ------------------
  |  Branch (256:31): [True: 2.24k, False: 811]
  |  Branch (256:40): [True: 1.83k, False: 404]
  ------------------
  257|  3.05k|                   "m"_mst.If(all_e && all_m && num_s >= n_subs - k) | // m=all e, >=(n-k) s
  ------------------
  |  Branch (257:31): [True: 2.24k, False: 811]
  |  Branch (257:40): [True: 1.88k, False: 358]
  |  Branch (257:49): [True: 1.85k, False: 27]
  ------------------
  258|  3.05k|                   "s"_mst.If(num_s >= n_subs - k + 1) |  // s= >=(n-k+1) s
  259|  3.05k|                   acc_tl; // timelock info
  260|  6.50k|            }
  261|  43.0M|    }
  262|      0|    assert(false);
  263|      0|}
_ZN10miniscript8internal16ComputeScriptLenENS_8FragmentENS_4TypeEmjmmNS_17MiniscriptContextE:
  266|  43.0M|                        size_t n_keys, MiniscriptContext ms_ctx) {
  267|  43.0M|    switch (fragment) {
  ------------------
  |  Branch (267:13): [True: 0, False: 43.0M]
  ------------------
  268|  8.60M|        case Fragment::JUST_1:
  ------------------
  |  Branch (268:9): [True: 8.60M, False: 34.4M]
  ------------------
  269|  16.3M|        case Fragment::JUST_0: return 1;
  ------------------
  |  Branch (269:9): [True: 7.73M, False: 35.2M]
  ------------------
  270|  18.8k|        case Fragment::PK_K: return IsTapscript(ms_ctx) ? 33 : 34;
  ------------------
  |  Branch (270:9): [True: 18.8k, False: 43.0M]
  |  Branch (270:37): [True: 17.1k, False: 1.72k]
  ------------------
  271|  18.4k|        case Fragment::PK_H: return 3 + 21;
  ------------------
  |  Branch (271:9): [True: 18.4k, False: 43.0M]
  ------------------
  272|  9.82k|        case Fragment::OLDER:
  ------------------
  |  Branch (272:9): [True: 9.82k, False: 43.0M]
  ------------------
  273|  14.5k|        case Fragment::AFTER: return 1 + BuildScript(k).size();
  ------------------
  |  Branch (273:9): [True: 4.75k, False: 43.0M]
  ------------------
  274|    211|        case Fragment::HASH256:
  ------------------
  |  Branch (274:9): [True: 211, False: 43.0M]
  ------------------
  275|    472|        case Fragment::SHA256: return 4 + 2 + 33;
  ------------------
  |  Branch (275:9): [True: 261, False: 43.0M]
  ------------------
  276|    689|        case Fragment::HASH160:
  ------------------
  |  Branch (276:9): [True: 689, False: 43.0M]
  ------------------
  277|  1.54k|        case Fragment::RIPEMD160: return 4 + 2 + 21;
  ------------------
  |  Branch (277:9): [True: 856, False: 43.0M]
  ------------------
  278|  2.77k|        case Fragment::MULTI: return 1 + BuildScript(n_keys).size() + BuildScript(k).size() + 34 * n_keys;
  ------------------
  |  Branch (278:9): [True: 2.77k, False: 43.0M]
  ------------------
  279|  4.39k|        case Fragment::MULTI_A: return (1 + 32 + 1) * n_keys + BuildScript(k).size() + 1;
  ------------------
  |  Branch (279:9): [True: 4.39k, False: 43.0M]
  ------------------
  280|  8.55M|        case Fragment::AND_V: return subsize;
  ------------------
  |  Branch (280:9): [True: 8.55M, False: 34.4M]
  ------------------
  281|  83.0k|        case Fragment::WRAP_V: return subsize + (sub0typ << "x"_mst);
  ------------------
  |  Branch (281:9): [True: 83.0k, False: 42.9M]
  ------------------
  282|   149k|        case Fragment::WRAP_S:
  ------------------
  |  Branch (282:9): [True: 149k, False: 42.8M]
  ------------------
  283|  9.32M|        case Fragment::WRAP_C:
  ------------------
  |  Branch (283:9): [True: 9.17M, False: 33.8M]
  ------------------
  284|  9.68M|        case Fragment::WRAP_N:
  ------------------
  |  Branch (284:9): [True: 359k, False: 42.6M]
  ------------------
  285|  9.69M|        case Fragment::AND_B:
  ------------------
  |  Branch (285:9): [True: 13.4k, False: 43.0M]
  ------------------
  286|  9.70M|        case Fragment::OR_B: return subsize + 1;
  ------------------
  |  Branch (286:9): [True: 4.79k, False: 43.0M]
  ------------------
  287|   299k|        case Fragment::WRAP_A:
  ------------------
  |  Branch (287:9): [True: 299k, False: 42.7M]
  ------------------
  288|   302k|        case Fragment::OR_C: return subsize + 2;
  ------------------
  |  Branch (288:9): [True: 3.65k, False: 43.0M]
  ------------------
  289|   185k|        case Fragment::WRAP_D:
  ------------------
  |  Branch (289:9): [True: 185k, False: 42.8M]
  ------------------
  290|   191k|        case Fragment::OR_D:
  ------------------
  |  Branch (290:9): [True: 5.69k, False: 43.0M]
  ------------------
  291|  7.85M|        case Fragment::OR_I:
  ------------------
  |  Branch (291:9): [True: 7.66M, False: 35.3M]
  ------------------
  292|  7.86M|        case Fragment::ANDOR: return subsize + 3;
  ------------------
  |  Branch (292:9): [True: 8.99k, False: 43.0M]
  ------------------
  293|   112k|        case Fragment::WRAP_J: return subsize + 4;
  ------------------
  |  Branch (293:9): [True: 112k, False: 42.9M]
  ------------------
  294|  6.50k|        case Fragment::THRESH: return subsize + n_subs + BuildScript(k).size();
  ------------------
  |  Branch (294:9): [True: 6.50k, False: 43.0M]
  ------------------
  295|  43.0M|    }
  296|      0|    assert(false);
  297|      0|}
_ZN10miniscript8internal12FindNextCharE4SpanIKcEc:
  423|   537k|{
  424|  25.9M|    for (int i = 0; i < (int)sp.size(); ++i) {
  ------------------
  |  Branch (424:21): [True: 25.9M, False: 275]
  ------------------
  425|  25.9M|        if (sp[i] == m) return i;
  ------------------
  |  Branch (425:13): [True: 529k, False: 25.3M]
  ------------------
  426|       |        // We only search within the current parentheses
  427|  25.3M|        if (sp[i] == ')') break;
  ------------------
  |  Branch (427:13): [True: 7.37k, False: 25.3M]
  ------------------
  428|  25.3M|    }
  429|  7.64k|    return -1;
  430|   537k|}

_ZNK10miniscript4TypeorES0_:
  138|   234M|    constexpr Type operator|(Type x) const { return Type(m_flags | x.m_flags); }
_ZN10miniscript4TypeC2Ej:
  131|   494M|    explicit constexpr Type(uint32_t flags) noexcept : m_flags(flags) {}
_ZN10miniscript11IsTapscriptENS_17MiniscriptContextE:
  246|  86.3M|{
  247|  86.3M|    switch (ms_ctx) {
  ------------------
  |  Branch (247:13): [True: 0, False: 86.3M]
  ------------------
  248|   560k|        case MiniscriptContext::P2WSH: return false;
  ------------------
  |  Branch (248:9): [True: 560k, False: 85.7M]
  ------------------
  249|  85.7M|        case MiniscriptContext::TAPSCRIPT: return true;
  ------------------
  |  Branch (249:9): [True: 85.7M, False: 560k]
  ------------------
  250|  86.3M|    }
  251|      0|    assert(false);
  252|      0|}
_ZNK10miniscript4TypelsES0_:
  144|   525M|    constexpr bool operator<<(Type x) const { return (x.m_flags & ~m_flags) == 0; }
_ZNK10miniscript4TypeanES0_:
  141|   183M|    constexpr Type operator&(Type x) const { return Type(m_flags & x.m_flags); }
_ZNK10miniscript4NodeI7CPubKeyE10ScriptSizeEv:
 1499|  43.0M|    size_t ScriptSize() const { return scriptlen; }
_ZNK10miniscript4NodeI7CPubKeyE7GetTypeEv:
 1557|  69.8M|    Type GetType() const { return typ; }
_ZN10miniscript8internal13MaxScriptSizeENS_17MiniscriptContextE:
  271|  8.19k|{
  272|  8.19k|    if (IsTapscript(ms_ctx)) {
  ------------------
  |  Branch (272:9): [True: 4.13k, False: 4.06k]
  ------------------
  273|       |        // Leaf scripts under Tapscript are not explicitly limited in size. They are only implicitly
  274|       |        // bounded by the maximum standard size of a spending transaction. Let the maximum script
  275|       |        // size conservatively be small enough such that even a maximum sized witness and a reasonably
  276|       |        // sized spending transaction can spend an output paying to this script without running into
  277|       |        // the maximum standard tx size limit.
  278|  4.13k|        constexpr auto max_size{MAX_STANDARD_TX_WEIGHT - TX_BODY_LEEWAY_WEIGHT - MAX_TAPSCRIPT_SAT_SIZE};
  279|  4.13k|        return max_size - GetSizeOfCompactSize(max_size);
  280|  4.13k|    }
  281|  4.06k|    return MAX_STANDARD_P2WSH_SCRIPT_SIZE;
  282|  8.19k|}
_ZN10miniscript11MakeNodeRefI7CPubKeyJNS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentEEEENSt3__110unique_ptrIKNS_4NodeIT_EENS6_14default_deleteISB_EEEEDpOT0_:
  196|  16.3M|NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
_ZN10miniscript4NodeI7CPubKeyEC2ENS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentEj:
 1670|  16.3M|        : fragment(nt), k(val), m_script_ctx{script_ctx}, ops(CalcOps()), ss(CalcStackSize()), ws(CalcWitnessSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
_ZNK10miniscript4NodeI7CPubKeyE7CalcOpsEv:
  944|  43.0M|    internal::Ops CalcOps() const {
  945|  43.0M|        switch (fragment) {
  ------------------
  |  Branch (945:17): [True: 0, False: 43.0M]
  ------------------
  946|  8.60M|            case Fragment::JUST_1: return {0, 0, {}};
  ------------------
  |  Branch (946:13): [True: 8.60M, False: 34.4M]
  ------------------
  947|  7.73M|            case Fragment::JUST_0: return {0, {}, 0};
  ------------------
  |  Branch (947:13): [True: 7.73M, False: 35.2M]
  ------------------
  948|  18.8k|            case Fragment::PK_K: return {0, 0, 0};
  ------------------
  |  Branch (948:13): [True: 18.8k, False: 43.0M]
  ------------------
  949|  18.4k|            case Fragment::PK_H: return {3, 0, 0};
  ------------------
  |  Branch (949:13): [True: 18.4k, False: 43.0M]
  ------------------
  950|  9.82k|            case Fragment::OLDER:
  ------------------
  |  Branch (950:13): [True: 9.82k, False: 43.0M]
  ------------------
  951|  14.5k|            case Fragment::AFTER: return {1, 0, {}};
  ------------------
  |  Branch (951:13): [True: 4.75k, False: 43.0M]
  ------------------
  952|    261|            case Fragment::SHA256:
  ------------------
  |  Branch (952:13): [True: 261, False: 43.0M]
  ------------------
  953|  1.11k|            case Fragment::RIPEMD160:
  ------------------
  |  Branch (953:13): [True: 856, False: 43.0M]
  ------------------
  954|  1.32k|            case Fragment::HASH256:
  ------------------
  |  Branch (954:13): [True: 211, False: 43.0M]
  ------------------
  955|  2.01k|            case Fragment::HASH160: return {4, 0, {}};
  ------------------
  |  Branch (955:13): [True: 689, False: 43.0M]
  ------------------
  956|  8.55M|            case Fragment::AND_V: return {subs[0]->ops.count + subs[1]->ops.count, subs[0]->ops.sat + subs[1]->ops.sat, {}};
  ------------------
  |  Branch (956:13): [True: 8.55M, False: 34.4M]
  ------------------
  957|  13.4k|            case Fragment::AND_B: {
  ------------------
  |  Branch (957:13): [True: 13.4k, False: 43.0M]
  ------------------
  958|  13.4k|                const auto count{1 + subs[0]->ops.count + subs[1]->ops.count};
  959|  13.4k|                const auto sat{subs[0]->ops.sat + subs[1]->ops.sat};
  960|  13.4k|                const auto dsat{subs[0]->ops.dsat + subs[1]->ops.dsat};
  961|  13.4k|                return {count, sat, dsat};
  962|  1.32k|            }
  963|  4.79k|            case Fragment::OR_B: {
  ------------------
  |  Branch (963:13): [True: 4.79k, False: 43.0M]
  ------------------
  964|  4.79k|                const auto count{1 + subs[0]->ops.count + subs[1]->ops.count};
  965|  4.79k|                const auto sat{(subs[0]->ops.sat + subs[1]->ops.dsat) | (subs[1]->ops.sat + subs[0]->ops.dsat)};
  966|  4.79k|                const auto dsat{subs[0]->ops.dsat + subs[1]->ops.dsat};
  967|  4.79k|                return {count, sat, dsat};
  968|  1.32k|            }
  969|  5.69k|            case Fragment::OR_D: {
  ------------------
  |  Branch (969:13): [True: 5.69k, False: 43.0M]
  ------------------
  970|  5.69k|                const auto count{3 + subs[0]->ops.count + subs[1]->ops.count};
  971|  5.69k|                const auto sat{subs[0]->ops.sat | (subs[1]->ops.sat + subs[0]->ops.dsat)};
  972|  5.69k|                const auto dsat{subs[0]->ops.dsat + subs[1]->ops.dsat};
  973|  5.69k|                return {count, sat, dsat};
  974|  1.32k|            }
  975|  3.65k|            case Fragment::OR_C: {
  ------------------
  |  Branch (975:13): [True: 3.65k, False: 43.0M]
  ------------------
  976|  3.65k|                const auto count{2 + subs[0]->ops.count + subs[1]->ops.count};
  977|  3.65k|                const auto sat{subs[0]->ops.sat | (subs[1]->ops.sat + subs[0]->ops.dsat)};
  978|  3.65k|                return {count, sat, {}};
  979|  1.32k|            }
  980|  7.66M|            case Fragment::OR_I: {
  ------------------
  |  Branch (980:13): [True: 7.66M, False: 35.3M]
  ------------------
  981|  7.66M|                const auto count{3 + subs[0]->ops.count + subs[1]->ops.count};
  982|  7.66M|                const auto sat{subs[0]->ops.sat | subs[1]->ops.sat};
  983|  7.66M|                const auto dsat{subs[0]->ops.dsat | subs[1]->ops.dsat};
  984|  7.66M|                return {count, sat, dsat};
  985|  1.32k|            }
  986|  8.99k|            case Fragment::ANDOR: {
  ------------------
  |  Branch (986:13): [True: 8.99k, False: 43.0M]
  ------------------
  987|  8.99k|                const auto count{3 + subs[0]->ops.count + subs[1]->ops.count + subs[2]->ops.count};
  988|  8.99k|                const auto sat{(subs[1]->ops.sat + subs[0]->ops.sat) | (subs[0]->ops.dsat + subs[2]->ops.sat)};
  989|  8.99k|                const auto dsat{subs[0]->ops.dsat + subs[2]->ops.dsat};
  990|  8.99k|                return {count, sat, dsat};
  991|  1.32k|            }
  992|  2.77k|            case Fragment::MULTI: return {1, (uint32_t)keys.size(), (uint32_t)keys.size()};
  ------------------
  |  Branch (992:13): [True: 2.77k, False: 43.0M]
  ------------------
  993|  4.39k|            case Fragment::MULTI_A: return {(uint32_t)keys.size() + 1, 0, 0};
  ------------------
  |  Branch (993:13): [True: 4.39k, False: 43.0M]
  ------------------
  994|   149k|            case Fragment::WRAP_S:
  ------------------
  |  Branch (994:13): [True: 149k, False: 42.8M]
  ------------------
  995|  9.32M|            case Fragment::WRAP_C:
  ------------------
  |  Branch (995:13): [True: 9.17M, False: 33.8M]
  ------------------
  996|  9.68M|            case Fragment::WRAP_N: return {1 + subs[0]->ops.count, subs[0]->ops.sat, subs[0]->ops.dsat};
  ------------------
  |  Branch (996:13): [True: 359k, False: 42.6M]
  ------------------
  997|   299k|            case Fragment::WRAP_A: return {2 + subs[0]->ops.count, subs[0]->ops.sat, subs[0]->ops.dsat};
  ------------------
  |  Branch (997:13): [True: 299k, False: 42.7M]
  ------------------
  998|   185k|            case Fragment::WRAP_D: return {3 + subs[0]->ops.count, subs[0]->ops.sat, 0};
  ------------------
  |  Branch (998:13): [True: 185k, False: 42.8M]
  ------------------
  999|   112k|            case Fragment::WRAP_J: return {4 + subs[0]->ops.count, subs[0]->ops.sat, 0};
  ------------------
  |  Branch (999:13): [True: 112k, False: 42.9M]
  ------------------
 1000|  83.0k|            case Fragment::WRAP_V: return {subs[0]->ops.count + (subs[0]->GetType() << "x"_mst), subs[0]->ops.sat, {}};
  ------------------
  |  Branch (1000:13): [True: 83.0k, False: 42.9M]
  ------------------
 1001|  6.50k|            case Fragment::THRESH: {
  ------------------
  |  Branch (1001:13): [True: 6.50k, False: 43.0M]
  ------------------
 1002|  6.50k|                uint32_t count = 0;
 1003|  6.50k|                auto sats = Vector(internal::MaxInt<uint32_t>(0));
 1004|   139k|                for (const auto& sub : subs) {
  ------------------
  |  Branch (1004:38): [True: 139k, False: 6.50k]
  ------------------
 1005|   139k|                    count += sub->ops.count + 1;
 1006|   139k|                    auto next_sats = Vector(sats[0] + sub->ops.dsat);
 1007|   107M|                    for (size_t j = 1; j < sats.size(); ++j) next_sats.push_back((sats[j] + sub->ops.dsat) | (sats[j - 1] + sub->ops.sat));
  ------------------
  |  Branch (1007:40): [True: 107M, False: 139k]
  ------------------
 1008|   139k|                    next_sats.push_back(sats[sats.size() - 1] + sub->ops.sat);
 1009|   139k|                    sats = std::move(next_sats);
 1010|   139k|                }
 1011|  6.50k|                assert(k <= sats.size());
 1012|  6.50k|                return {count, sats[k], sats[0]};
 1013|  6.50k|            }
 1014|  43.0M|        }
 1015|      0|        assert(false);
 1016|      0|    }
_ZN10miniscript8internal6MaxIntIjEC2Ej:
  356|   206M|    MaxInt(I val) : valid(true), value(val) {}
_ZN10miniscript8internal6MaxIntIjEC2Ev:
  355|   451M|    MaxInt() : valid(false), value(0) {}
_ZN10miniscript8internal3OpsC2EjNS0_6MaxIntIjEES3_:
  378|  43.0M|    Ops(uint32_t in_count, MaxInt<uint32_t> in_sat, MaxInt<uint32_t> in_dsat) : count(in_count), sat(in_sat), dsat(in_dsat) {};
_ZN10miniscript8internalplERKNS0_6MaxIntIjEES4_:
  358|   493M|    friend MaxInt<I> operator+(const MaxInt<I>& a, const MaxInt<I>& b) {
  359|   493M|        if (!a.valid || !b.valid) return {};
  ------------------
  |  Branch (359:13): [True: 395M, False: 98.5M]
  |  Branch (359:25): [True: 6.09M, False: 92.4M]
  ------------------
  360|  92.4M|        return a.value + b.value;
  361|   493M|    }
_ZN10miniscript8internalorERKNS0_6MaxIntIjEES4_:
  363|   245M|    friend MaxInt<I> operator|(const MaxInt<I>& a, const MaxInt<I>& b) {
  364|   245M|        if (!a.valid) return b;
  ------------------
  |  Branch (364:13): [True: 207M, False: 38.5M]
  ------------------
  365|  38.5M|        if (!b.valid) return a;
  ------------------
  |  Branch (365:13): [True: 4.44M, False: 34.1M]
  ------------------
  366|  34.1M|        return std::max(a.value, b.value);
  367|  38.5M|    }
_ZNK10miniscript4NodeI7CPubKeyE13CalcStackSizeEv:
 1018|  43.0M|    internal::StackSize CalcStackSize() const {
 1019|  43.0M|        using namespace internal;
 1020|  43.0M|        switch (fragment) {
  ------------------
  |  Branch (1020:17): [True: 0, False: 43.0M]
  ------------------
 1021|  7.73M|            case Fragment::JUST_0: return {{}, SatInfo::Push()};
  ------------------
  |  Branch (1021:13): [True: 7.73M, False: 35.2M]
  ------------------
 1022|  8.60M|            case Fragment::JUST_1: return {SatInfo::Push(), {}};
  ------------------
  |  Branch (1022:13): [True: 8.60M, False: 34.4M]
  ------------------
 1023|  9.82k|            case Fragment::OLDER:
  ------------------
  |  Branch (1023:13): [True: 9.82k, False: 43.0M]
  ------------------
 1024|  14.5k|            case Fragment::AFTER: return {SatInfo::Push() + SatInfo::Nop(), {}};
  ------------------
  |  Branch (1024:13): [True: 4.75k, False: 43.0M]
  ------------------
 1025|  18.8k|            case Fragment::PK_K: return {SatInfo::Push()};
  ------------------
  |  Branch (1025:13): [True: 18.8k, False: 43.0M]
  ------------------
 1026|  18.4k|            case Fragment::PK_H: return {SatInfo::OP_DUP() + SatInfo::Hash() + SatInfo::Push() + SatInfo::OP_EQUALVERIFY()};
  ------------------
  |  Branch (1026:13): [True: 18.4k, False: 43.0M]
  ------------------
 1027|    261|            case Fragment::SHA256:
  ------------------
  |  Branch (1027:13): [True: 261, False: 43.0M]
  ------------------
 1028|  1.11k|            case Fragment::RIPEMD160:
  ------------------
  |  Branch (1028:13): [True: 856, False: 43.0M]
  ------------------
 1029|  1.32k|            case Fragment::HASH256:
  ------------------
  |  Branch (1029:13): [True: 211, False: 43.0M]
  ------------------
 1030|  2.01k|            case Fragment::HASH160: return {
  ------------------
  |  Branch (1030:13): [True: 689, False: 43.0M]
  ------------------
 1031|  2.01k|                SatInfo::OP_SIZE() + SatInfo::Push() + SatInfo::OP_EQUALVERIFY() + SatInfo::Hash() + SatInfo::Push() + SatInfo::OP_EQUAL(),
 1032|  2.01k|                {}
 1033|  2.01k|            };
 1034|  8.99k|            case Fragment::ANDOR: {
  ------------------
  |  Branch (1034:13): [True: 8.99k, False: 43.0M]
  ------------------
 1035|  8.99k|                const auto& x{subs[0]->ss};
 1036|  8.99k|                const auto& y{subs[1]->ss};
 1037|  8.99k|                const auto& z{subs[2]->ss};
 1038|  8.99k|                return {
 1039|  8.99k|                    (x.sat + SatInfo::If() + y.sat) | (x.dsat + SatInfo::If() + z.sat),
 1040|  8.99k|                    x.dsat + SatInfo::If() + z.dsat
 1041|  8.99k|                };
 1042|  1.32k|            }
 1043|  8.55M|            case Fragment::AND_V: {
  ------------------
  |  Branch (1043:13): [True: 8.55M, False: 34.4M]
  ------------------
 1044|  8.55M|                const auto& x{subs[0]->ss};
 1045|  8.55M|                const auto& y{subs[1]->ss};
 1046|  8.55M|                return {x.sat + y.sat, {}};
 1047|  1.32k|            }
 1048|  13.4k|            case Fragment::AND_B: {
  ------------------
  |  Branch (1048:13): [True: 13.4k, False: 43.0M]
  ------------------
 1049|  13.4k|                const auto& x{subs[0]->ss};
 1050|  13.4k|                const auto& y{subs[1]->ss};
 1051|  13.4k|                return {x.sat + y.sat + SatInfo::BinaryOp(), x.dsat + y.dsat + SatInfo::BinaryOp()};
 1052|  1.32k|            }
 1053|  4.79k|            case Fragment::OR_B: {
  ------------------
  |  Branch (1053:13): [True: 4.79k, False: 43.0M]
  ------------------
 1054|  4.79k|                const auto& x{subs[0]->ss};
 1055|  4.79k|                const auto& y{subs[1]->ss};
 1056|  4.79k|                return {
 1057|  4.79k|                    ((x.sat + y.dsat) | (x.dsat + y.sat)) + SatInfo::BinaryOp(),
 1058|  4.79k|                    x.dsat + y.dsat + SatInfo::BinaryOp()
 1059|  4.79k|                };
 1060|  1.32k|            }
 1061|  3.65k|            case Fragment::OR_C: {
  ------------------
  |  Branch (1061:13): [True: 3.65k, False: 43.0M]
  ------------------
 1062|  3.65k|                const auto& x{subs[0]->ss};
 1063|  3.65k|                const auto& y{subs[1]->ss};
 1064|  3.65k|                return {(x.sat + SatInfo::If()) | (x.dsat + SatInfo::If() + y.sat), {}};
 1065|  1.32k|            }
 1066|  5.69k|            case Fragment::OR_D: {
  ------------------
  |  Branch (1066:13): [True: 5.69k, False: 43.0M]
  ------------------
 1067|  5.69k|                const auto& x{subs[0]->ss};
 1068|  5.69k|                const auto& y{subs[1]->ss};
 1069|  5.69k|                return {
 1070|  5.69k|                    (x.sat + SatInfo::OP_IFDUP(true) + SatInfo::If()) | (x.dsat + SatInfo::OP_IFDUP(false) + SatInfo::If() + y.sat),
 1071|  5.69k|                    x.dsat + SatInfo::OP_IFDUP(false) + SatInfo::If() + y.dsat
 1072|  5.69k|                };
 1073|  1.32k|            }
 1074|  7.66M|            case Fragment::OR_I: {
  ------------------
  |  Branch (1074:13): [True: 7.66M, False: 35.3M]
  ------------------
 1075|  7.66M|                const auto& x{subs[0]->ss};
 1076|  7.66M|                const auto& y{subs[1]->ss};
 1077|  7.66M|                return {SatInfo::If() + (x.sat | y.sat), SatInfo::If() + (x.dsat | y.dsat)};
 1078|  1.32k|            }
 1079|       |            // multi(k, key1, key2, ..., key_n) starts off with k+1 stack elements (a 0, plus k
 1080|       |            // signatures), then reaches n+k+3 stack elements after pushing the n keys, plus k and
 1081|       |            // n itself, and ends with 1 stack element (success or failure). Thus, it net removes
 1082|       |            // k elements (from k+1 to 1), while reaching k+n+2 more than it ends with.
 1083|  2.77k|            case Fragment::MULTI: return {SatInfo(k, k + keys.size() + 2)};
  ------------------
  |  Branch (1083:13): [True: 2.77k, False: 43.0M]
  ------------------
 1084|       |            // multi_a(k, key1, key2, ..., key_n) starts off with n stack elements (the
 1085|       |            // signatures), reaches 1 more (after the first key push), and ends with 1. Thus it net
 1086|       |            // removes n-1 elements (from n to 1) while reaching n more than it ends with.
 1087|  4.39k|            case Fragment::MULTI_A: return {SatInfo(keys.size() - 1, keys.size())};
  ------------------
  |  Branch (1087:13): [True: 4.39k, False: 43.0M]
  ------------------
 1088|   299k|            case Fragment::WRAP_A:
  ------------------
  |  Branch (1088:13): [True: 299k, False: 42.7M]
  ------------------
 1089|   658k|            case Fragment::WRAP_N:
  ------------------
  |  Branch (1089:13): [True: 359k, False: 42.6M]
  ------------------
 1090|   808k|            case Fragment::WRAP_S: return subs[0]->ss;
  ------------------
  |  Branch (1090:13): [True: 149k, False: 42.8M]
  ------------------
 1091|  9.17M|            case Fragment::WRAP_C: return {
  ------------------
  |  Branch (1091:13): [True: 9.17M, False: 33.8M]
  ------------------
 1092|  9.17M|                subs[0]->ss.sat + SatInfo::OP_CHECKSIG(),
 1093|  9.17M|                subs[0]->ss.dsat + SatInfo::OP_CHECKSIG()
 1094|  9.17M|            };
 1095|   185k|            case Fragment::WRAP_D: return {
  ------------------
  |  Branch (1095:13): [True: 185k, False: 42.8M]
  ------------------
 1096|   185k|                SatInfo::OP_DUP() + SatInfo::If() + subs[0]->ss.sat,
 1097|   185k|                SatInfo::OP_DUP() + SatInfo::If()
 1098|   185k|            };
 1099|  83.0k|            case Fragment::WRAP_V: return {subs[0]->ss.sat + SatInfo::OP_VERIFY(), {}};
  ------------------
  |  Branch (1099:13): [True: 83.0k, False: 42.9M]
  ------------------
 1100|   112k|            case Fragment::WRAP_J: return {
  ------------------
  |  Branch (1100:13): [True: 112k, False: 42.9M]
  ------------------
 1101|   112k|                SatInfo::OP_SIZE() + SatInfo::OP_0NOTEQUAL() + SatInfo::If() + subs[0]->ss.sat,
 1102|   112k|                SatInfo::OP_SIZE() + SatInfo::OP_0NOTEQUAL() + SatInfo::If()
 1103|   112k|            };
 1104|  6.50k|            case Fragment::THRESH: {
  ------------------
  |  Branch (1104:13): [True: 6.50k, False: 43.0M]
  ------------------
 1105|       |                // sats[j] is the SatInfo corresponding to all traces reaching j satisfactions.
 1106|  6.50k|                auto sats = Vector(SatInfo::Empty());
 1107|   146k|                for (size_t i = 0; i < subs.size(); ++i) {
  ------------------
  |  Branch (1107:36): [True: 139k, False: 6.50k]
  ------------------
 1108|       |                    // Loop over the subexpressions, processing them one by one. After adding
 1109|       |                    // element i we need to add OP_ADD (if i>0).
 1110|   139k|                    auto add = i ? SatInfo::BinaryOp() : SatInfo::Empty();
  ------------------
  |  Branch (1110:32): [True: 133k, False: 6.50k]
  ------------------
 1111|       |                    // Construct a variable that will become the next sats, starting with index 0.
 1112|   139k|                    auto next_sats = Vector(sats[0] + subs[i]->ss.dsat + add);
 1113|       |                    // Then loop to construct next_sats[1..i].
 1114|   107M|                    for (size_t j = 1; j < sats.size(); ++j) {
  ------------------
  |  Branch (1114:40): [True: 107M, False: 139k]
  ------------------
 1115|   107M|                        next_sats.push_back(((sats[j] + subs[i]->ss.dsat) | (sats[j - 1] + subs[i]->ss.sat)) + add);
 1116|   107M|                    }
 1117|       |                    // Finally construct next_sats[i+1].
 1118|   139k|                    next_sats.push_back(sats[sats.size() - 1] + subs[i]->ss.sat + add);
 1119|       |                    // Switch over.
 1120|   139k|                    sats = std::move(next_sats);
 1121|   139k|                }
 1122|       |                // To satisfy thresh we need k satisfactions; to dissatisfy we need 0. In both
 1123|       |                // cases a push of k and an OP_EQUAL follow.
 1124|  6.50k|                return {
 1125|  6.50k|                    sats[k] + SatInfo::Push() + SatInfo::OP_EQUAL(),
 1126|  6.50k|                    sats[0] + SatInfo::Push() + SatInfo::OP_EQUAL()
 1127|  6.50k|                };
 1128|   658k|            }
 1129|  43.0M|        }
 1130|      0|        assert(false);
 1131|      0|    }
_ZN10miniscript8internal7SatInfoC2Ev:
  431|   317M|    constexpr SatInfo() noexcept : valid(false), netdiff(0), exec(0) {}
_ZN10miniscript8internal7SatInfo4PushEv:
  461|  16.4M|    static constexpr SatInfo Push() noexcept { return {-1, 0}; }
_ZN10miniscript8internal9StackSizeC2ENS0_7SatInfoES2_:
  485|  42.1M|    constexpr StackSize(SatInfo in_sat, SatInfo in_dsat) noexcept : sat(in_sat), dsat(in_dsat) {};
_ZN10miniscript8internalplERKNS0_7SatInfoES3_:
  449|   366M|    {
  450|       |        // Concatenation with an empty set yields an empty set.
  451|   366M|        if (!a.valid || !b.valid) return {};
  ------------------
  |  Branch (451:13): [True: 288M, False: 77.9M]
  |  Branch (451:25): [True: 3.37M, False: 74.5M]
  ------------------
  452|       |        // Otherwise, the maximum stack size difference for the combined scripts is the sum of the
  453|       |        // netdiffs, and the maximum stack size difference anywhere is either b.exec (if the
  454|       |        // maximum occurred in b) or b.netdiff+a.exec (if the maximum occurred in a).
  455|  74.5M|        return {a.netdiff + b.netdiff, std::max(b.exec, b.netdiff + a.exec)};
  456|   366M|    }
_ZN10miniscript8internal7SatInfo3NopEv:
  465|  14.5k|    static constexpr SatInfo Nop() noexcept { return {0, 0}; }
_ZN10miniscript8internal9StackSizeC2ENS0_7SatInfoE:
  486|  44.4k|    constexpr StackSize(SatInfo in_both) noexcept : sat(in_both), dsat(in_both) {};
_ZN10miniscript8internal7SatInfo6OP_DUPEv:
  472|   389k|    static constexpr SatInfo OP_DUP() noexcept { return {-1, 0}; }
_ZN10miniscript8internal7SatInfo4HashEv:
  463|  20.4k|    static constexpr SatInfo Hash() noexcept { return {0, 0}; }
_ZN10miniscript8internal7SatInfo14OP_EQUALVERIFYEv:
  474|  20.4k|    static constexpr SatInfo OP_EQUALVERIFY() noexcept { return {2, 2}; }
_ZN10miniscript8internal7SatInfo7OP_SIZEEv:
  476|   227k|    static constexpr SatInfo OP_SIZE() noexcept { return {-1, 0}; }
_ZN10miniscript8internal7SatInfo8OP_EQUALEv:
  475|  15.0k|    static constexpr SatInfo OP_EQUAL() noexcept { return {1, 1}; }
_ZN10miniscript8internalorERKNS0_7SatInfoES3_:
  439|   122M|    {
  440|       |        // Union with an empty set is itself.
  441|   122M|        if (!a.valid) return b;
  ------------------
  |  Branch (441:13): [True: 103M, False: 19.2M]
  ------------------
  442|  19.2M|        if (!b.valid) return a;
  ------------------
  |  Branch (442:13): [True: 2.22M, False: 17.0M]
  ------------------
  443|       |        // Otherwise the netdiff and exec of the union is the maximum of the individual values.
  444|  17.0M|        return {std::max(a.netdiff, b.netdiff), std::max(a.exec, b.exec)};
  445|  19.2M|    }
_ZN10miniscript8internal7SatInfo2IfEv:
  467|  15.9M|    static constexpr SatInfo If() noexcept { return {1, 1}; }
_ZN10miniscript8internal7SatInfo8BinaryOpEv:
  469|   169k|    static constexpr SatInfo BinaryOp() noexcept { return {1, 1}; }
_ZN10miniscript8internal7SatInfo8OP_IFDUPEb:
  473|  17.0k|    static constexpr SatInfo OP_IFDUP(bool nonzero) noexcept { return {nonzero ? -1 : 0, 0}; }
  ------------------
  |  Branch (473:72): [True: 5.69k, False: 11.3k]
  ------------------
_ZN10miniscript8internal7SatInfoC2Eii:
  435|   143M|        valid{true}, netdiff{in_netdiff}, exec{in_exec} {}
_ZN10miniscript8internal7SatInfo11OP_CHECKSIGEv:
  477|  18.3M|    static constexpr SatInfo OP_CHECKSIG() noexcept { return {1, 1}; }
_ZN10miniscript8internal7SatInfo9OP_VERIFYEv:
  479|  83.0k|    static constexpr SatInfo OP_VERIFY() noexcept { return {1, 1}; }
_ZN10miniscript8internal7SatInfo12OP_0NOTEQUALEv:
  478|   225k|    static constexpr SatInfo OP_0NOTEQUAL() noexcept { return {0, 0}; }
_ZN10miniscript8internal7SatInfo5EmptyEv:
  459|  13.0k|    static constexpr SatInfo Empty() noexcept { return {0, 0}; }
_ZNK10miniscript4NodeI7CPubKeyE15CalcWitnessSizeEv:
 1133|  43.0M|    internal::WitnessSize CalcWitnessSize() const {
 1134|  43.0M|        const uint32_t sig_size = IsTapscript(m_script_ctx) ? 1 + 65 : 1 + 72;
  ------------------
  |  Branch (1134:35): [True: 42.7M, False: 272k]
  ------------------
 1135|  43.0M|        const uint32_t pubkey_size = IsTapscript(m_script_ctx) ? 1 + 32 : 1 + 33;
  ------------------
  |  Branch (1135:38): [True: 42.7M, False: 272k]
  ------------------
 1136|  43.0M|        switch (fragment) {
  ------------------
  |  Branch (1136:17): [True: 0, False: 43.0M]
  ------------------
 1137|  7.73M|            case Fragment::JUST_0: return {{}, 0};
  ------------------
  |  Branch (1137:13): [True: 7.73M, False: 35.2M]
  ------------------
 1138|  8.60M|            case Fragment::JUST_1:
  ------------------
  |  Branch (1138:13): [True: 8.60M, False: 34.4M]
  ------------------
 1139|  8.61M|            case Fragment::OLDER:
  ------------------
  |  Branch (1139:13): [True: 9.82k, False: 43.0M]
  ------------------
 1140|  8.62M|            case Fragment::AFTER: return {0, {}};
  ------------------
  |  Branch (1140:13): [True: 4.75k, False: 43.0M]
  ------------------
 1141|  18.8k|            case Fragment::PK_K: return {sig_size, 1};
  ------------------
  |  Branch (1141:13): [True: 18.8k, False: 43.0M]
  ------------------
 1142|  18.4k|            case Fragment::PK_H: return {sig_size + pubkey_size, 1 + pubkey_size};
  ------------------
  |  Branch (1142:13): [True: 18.4k, False: 43.0M]
  ------------------
 1143|    261|            case Fragment::SHA256:
  ------------------
  |  Branch (1143:13): [True: 261, False: 43.0M]
  ------------------
 1144|  1.11k|            case Fragment::RIPEMD160:
  ------------------
  |  Branch (1144:13): [True: 856, False: 43.0M]
  ------------------
 1145|  1.32k|            case Fragment::HASH256:
  ------------------
  |  Branch (1145:13): [True: 211, False: 43.0M]
  ------------------
 1146|  2.01k|            case Fragment::HASH160: return {1 + 32, {}};
  ------------------
  |  Branch (1146:13): [True: 689, False: 43.0M]
  ------------------
 1147|  8.99k|            case Fragment::ANDOR: {
  ------------------
  |  Branch (1147:13): [True: 8.99k, False: 43.0M]
  ------------------
 1148|  8.99k|                const auto sat{(subs[0]->ws.sat + subs[1]->ws.sat) | (subs[0]->ws.dsat + subs[2]->ws.sat)};
 1149|  8.99k|                const auto dsat{subs[0]->ws.dsat + subs[2]->ws.dsat};
 1150|  8.99k|                return {sat, dsat};
 1151|  1.32k|            }
 1152|  8.55M|            case Fragment::AND_V: return {subs[0]->ws.sat + subs[1]->ws.sat, {}};
  ------------------
  |  Branch (1152:13): [True: 8.55M, False: 34.4M]
  ------------------
 1153|  13.4k|            case Fragment::AND_B: return {subs[0]->ws.sat + subs[1]->ws.sat, subs[0]->ws.dsat + subs[1]->ws.dsat};
  ------------------
  |  Branch (1153:13): [True: 13.4k, False: 43.0M]
  ------------------
 1154|  4.79k|            case Fragment::OR_B: {
  ------------------
  |  Branch (1154:13): [True: 4.79k, False: 43.0M]
  ------------------
 1155|  4.79k|                const auto sat{(subs[0]->ws.dsat + subs[1]->ws.sat) | (subs[0]->ws.sat + subs[1]->ws.dsat)};
 1156|  4.79k|                const auto dsat{subs[0]->ws.dsat + subs[1]->ws.dsat};
 1157|  4.79k|                return {sat, dsat};
 1158|  1.32k|            }
 1159|  3.65k|            case Fragment::OR_C: return {subs[0]->ws.sat | (subs[0]->ws.dsat + subs[1]->ws.sat), {}};
  ------------------
  |  Branch (1159:13): [True: 3.65k, False: 43.0M]
  ------------------
 1160|  5.69k|            case Fragment::OR_D: return {subs[0]->ws.sat | (subs[0]->ws.dsat + subs[1]->ws.sat), subs[0]->ws.dsat + subs[1]->ws.dsat};
  ------------------
  |  Branch (1160:13): [True: 5.69k, False: 43.0M]
  ------------------
 1161|  7.66M|            case Fragment::OR_I: return {(subs[0]->ws.sat + 1 + 1) | (subs[1]->ws.sat + 1), (subs[0]->ws.dsat + 1 + 1) | (subs[1]->ws.dsat + 1)};
  ------------------
  |  Branch (1161:13): [True: 7.66M, False: 35.3M]
  ------------------
 1162|  2.77k|            case Fragment::MULTI: return {k * sig_size + 1, k + 1};
  ------------------
  |  Branch (1162:13): [True: 2.77k, False: 43.0M]
  ------------------
 1163|  4.39k|            case Fragment::MULTI_A: return {k * sig_size + static_cast<uint32_t>(keys.size()) - k, static_cast<uint32_t>(keys.size())};
  ------------------
  |  Branch (1163:13): [True: 4.39k, False: 43.0M]
  ------------------
 1164|   299k|            case Fragment::WRAP_A:
  ------------------
  |  Branch (1164:13): [True: 299k, False: 42.7M]
  ------------------
 1165|   658k|            case Fragment::WRAP_N:
  ------------------
  |  Branch (1165:13): [True: 359k, False: 42.6M]
  ------------------
 1166|   808k|            case Fragment::WRAP_S:
  ------------------
  |  Branch (1166:13): [True: 149k, False: 42.8M]
  ------------------
 1167|  9.98M|            case Fragment::WRAP_C: return subs[0]->ws;
  ------------------
  |  Branch (1167:13): [True: 9.17M, False: 33.8M]
  ------------------
 1168|   185k|            case Fragment::WRAP_D: return {1 + 1 + subs[0]->ws.sat, 1};
  ------------------
  |  Branch (1168:13): [True: 185k, False: 42.8M]
  ------------------
 1169|  83.0k|            case Fragment::WRAP_V: return {subs[0]->ws.sat, {}};
  ------------------
  |  Branch (1169:13): [True: 83.0k, False: 42.9M]
  ------------------
 1170|   112k|            case Fragment::WRAP_J: return {subs[0]->ws.sat, 1};
  ------------------
  |  Branch (1170:13): [True: 112k, False: 42.9M]
  ------------------
 1171|  6.50k|            case Fragment::THRESH: {
  ------------------
  |  Branch (1171:13): [True: 6.50k, False: 43.0M]
  ------------------
 1172|  6.50k|                auto sats = Vector(internal::MaxInt<uint32_t>(0));
 1173|   139k|                for (const auto& sub : subs) {
  ------------------
  |  Branch (1173:38): [True: 139k, False: 6.50k]
  ------------------
 1174|   139k|                    auto next_sats = Vector(sats[0] + sub->ws.dsat);
 1175|   107M|                    for (size_t j = 1; j < sats.size(); ++j) next_sats.push_back((sats[j] + sub->ws.dsat) | (sats[j - 1] + sub->ws.sat));
  ------------------
  |  Branch (1175:40): [True: 107M, False: 139k]
  ------------------
 1176|   139k|                    next_sats.push_back(sats[sats.size() - 1] + sub->ws.sat);
 1177|   139k|                    sats = std::move(next_sats);
 1178|   139k|                }
 1179|  6.50k|                assert(k <= sats.size());
 1180|  6.50k|                return {sats[k], sats[0]};
 1181|  6.50k|            }
 1182|  43.0M|        }
 1183|      0|        assert(false);
 1184|      0|    }
_ZN10miniscript8internal11WitnessSizeC2ENS0_6MaxIntIjEES3_:
  495|  33.0M|    WitnessSize(MaxInt<uint32_t> in_sat, MaxInt<uint32_t> in_dsat) : sat(in_sat), dsat(in_dsat) {};
_ZNK10miniscript4NodeI7CPubKeyE8CalcTypeEv:
  731|  43.0M|    Type CalcType() const {
  732|  43.0M|        using namespace internal;
  733|       |
  734|       |        // THRESH has a variable number of subexpressions
  735|  43.0M|        std::vector<Type> sub_types;
  736|  43.0M|        if (fragment == Fragment::THRESH) {
  ------------------
  |  Branch (736:13): [True: 6.50k, False: 43.0M]
  ------------------
  737|   139k|            for (const auto& sub : subs) sub_types.push_back(sub->GetType());
  ------------------
  |  Branch (737:34): [True: 139k, False: 6.50k]
  ------------------
  738|  6.50k|        }
  739|       |        // All other nodes than THRESH can be computed just from the types of the 0-3 subexpressions.
  740|  43.0M|        static constexpr auto NONE_MST{""_mst};
  741|  43.0M|        Type x = subs.size() > 0 ? subs[0]->GetType() : NONE_MST;
  ------------------
  |  Branch (741:18): [True: 26.6M, False: 16.4M]
  ------------------
  742|  43.0M|        Type y = subs.size() > 1 ? subs[1]->GetType() : NONE_MST;
  ------------------
  |  Branch (742:18): [True: 16.2M, False: 26.7M]
  ------------------
  743|  43.0M|        Type z = subs.size() > 2 ? subs[2]->GetType() : NONE_MST;
  ------------------
  |  Branch (743:18): [True: 11.2k, False: 43.0M]
  ------------------
  744|       |
  745|  43.0M|        return SanitizeType(ComputeType(fragment, x, y, z, sub_types, k, data.size(), subs.size(), keys.size(), m_script_ctx));
  746|  43.0M|    }
_ZNK10miniscript4NodeI7CPubKeyE13CalcScriptLenEv:
  570|  43.0M|    size_t CalcScriptLen() const {
  571|  43.0M|        size_t subsize = 0;
  572|  43.0M|        for (const auto& sub : subs) {
  ------------------
  |  Branch (572:30): [True: 43.0M, False: 43.0M]
  ------------------
  573|  43.0M|            subsize += sub->ScriptSize();
  574|  43.0M|        }
  575|  43.0M|        static constexpr auto NONE_MST{""_mst};
  576|  43.0M|        Type sub0type = subs.size() > 0 ? subs[0]->GetType() : NONE_MST;
  ------------------
  |  Branch (576:25): [True: 26.6M, False: 16.4M]
  ------------------
  577|  43.0M|        return internal::ComputeScriptLen(fragment, sub0type, subsize, k, subs.size(), keys.size(), m_script_ctx);
  578|  43.0M|    }
_ZN10miniscript11MakeNodeRefI7CPubKeyJNS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentENSt3__16vectorIS1_NS6_9allocatorIS1_EEEEEEENS6_10unique_ptrIKNS_4NodeIT_EENS6_14default_deleteISF_EEEEDpOT0_:
  196|  37.3k|NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
_ZN10miniscript4NodeI7CPubKeyEC2ENS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentENSt3__16vectorIS1_NS7_9allocatorIS1_EEEEj:
 1666|  44.4k|        : fragment(nt), k(val), keys(std::move(key)), m_script_ctx{script_ctx}, ops(CalcOps()), ss(CalcStackSize()), ws(CalcWitnessSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
_ZN10miniscript4NodeI7CPubKeyEC2ENS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentENSt3__16vectorIhNS7_9allocatorIhEEEEj:
 1662|  2.01k|        : fragment(nt), k(val), data(std::move(arg)), m_script_ctx{script_ctx}, ops(CalcOps()), ss(CalcStackSize()), ws(CalcWitnessSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
_ZN10miniscript11MakeNodeRefI7CPubKeyJNS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentENSt3__16vectorIS1_NS6_9allocatorIS1_EEEERKlEEENS6_10unique_ptrIKNS_4NodeIT_EENS6_14default_deleteISH_EEEEDpOT0_:
  196|  7.16k|NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
_ZN10miniscript11MakeNodeRefI7CPubKeyJNS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentENSt3__16vectorINS6_10unique_ptrIKNS_4NodeIS1_EENS6_14default_deleteISB_EEEENS6_9allocatorISE_EEEEEEENS8_IKNS9_IT_EENSC_ISK_EEEEDpOT0_:
  196|  21.0M|NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
_ZN10miniscript4NodeI7CPubKeyEC2ENS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentENSt3__16vectorINS7_10unique_ptrIKS2_NS7_14default_deleteISA_EEEENS7_9allocatorISD_EEEEj:
 1668|  26.6M|        : fragment(nt), k(val), subs(std::move(sub)), m_script_ctx{script_ctx}, ops(CalcOps()), ss(CalcStackSize()), ws(CalcWitnessSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
_ZN10miniscript4NodeI7CPubKeyED2Ev:
  520|  43.0M|    ~Node() {
  521|  86.0M|        while (!subs.empty()) {
  ------------------
  |  Branch (521:16): [True: 43.0M, False: 43.0M]
  ------------------
  522|  43.0M|            auto node = std::move(subs.back());
  523|  43.0M|            subs.pop_back();
  524|  85.8M|            while (!node->subs.empty()) {
  ------------------
  |  Branch (524:20): [True: 42.8M, False: 43.0M]
  ------------------
  525|  42.8M|                subs.push_back(std::move(node->subs.back()));
  526|  42.8M|                node->subs.pop_back();
  527|  42.8M|            }
  528|  43.0M|        }
  529|  43.0M|    }
_ZN10miniscript8internal9BuildBackI7CPubKeyEEvNS_17MiniscriptContextENS_8FragmentERNSt3__16vectorINS5_10unique_ptrIKNS_4NodeIT_EENS5_14default_deleteISB_EEEENS5_9allocatorISE_EEEEb:
 1777|  5.55M|{
 1778|  5.55M|    NodeRef<Key> child = std::move(constructed.back());
 1779|  5.55M|    constructed.pop_back();
 1780|  5.55M|    if (reverse) {
  ------------------
  |  Branch (1780:9): [True: 0, False: 5.55M]
  ------------------
 1781|      0|        constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, script_ctx, nt, Vector(std::move(child), std::move(constructed.back())));
 1782|  5.55M|    } else {
 1783|  5.55M|        constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, script_ctx, nt, Vector(std::move(constructed.back()), std::move(child)));
 1784|  5.55M|    }
 1785|  5.55M|}
_ZN10miniscript11MakeNodeRefI7CPubKeyJNS_8internal10NoDupCheckERKNS_17MiniscriptContextERNS_8FragmentENSt3__16vectorINS9_10unique_ptrIKNS_4NodeIS1_EENS9_14default_deleteISE_EEEENS9_9allocatorISH_EEEEEEENSB_IKNSC_IT_EENSF_ISN_EEEEDpOT0_:
  196|  5.55M|NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
_ZN10miniscript11MakeNodeRefI7CPubKeyJNS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentENSt3__16vectorINS6_10unique_ptrIKNS_4NodeIS1_EENS6_14default_deleteISB_EEEENS6_9allocatorISE_EEEERlEEENS8_IKNS9_IT_EENSC_ISL_EEEEDpOT0_:
  196|  6.50k|NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
miniscript.cpp:_ZNK10miniscript4NodeI7CPubKeyE17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_:
 1441|  5.43k|    {
 1442|       |        // We cannot use a lambda here, as lambdas are non assignable, and the set operations
 1443|       |        // below require moving the comparators around.
 1444|  5.43k|        struct Comp {
 1445|  5.43k|            const Ctx* ctx_ptr;
 1446|  5.43k|            Comp(const Ctx& ctx) : ctx_ptr(&ctx) {}
 1447|  5.43k|            bool operator()(const Key& a, const Key& b) const { return ctx_ptr->KeyCompare(a, b); }
 1448|  5.43k|        };
 1449|       |
 1450|       |        // state in the recursive computation:
 1451|       |        // - std::nullopt means "this node has duplicates"
 1452|       |        // - an std::set means "this node has no duplicate keys, and they are: ...".
 1453|  5.43k|        using keyset = std::set<Key, Comp>;
 1454|  5.43k|        using state = std::optional<keyset>;
 1455|       |
 1456|  5.43k|        auto upfn = [&ctx](const Node& node, Span<state> subs) -> state {
 1457|       |            // If this node is already known to have duplicates, nothing left to do.
 1458|  5.43k|            if (node.has_duplicate_keys.has_value() && *node.has_duplicate_keys) return {};
 1459|       |
 1460|       |            // Check if one of the children is already known to have duplicates.
 1461|  5.43k|            for (auto& sub : subs) {
 1462|  5.43k|                if (!sub.has_value()) {
 1463|  5.43k|                    node.has_duplicate_keys = true;
 1464|  5.43k|                    return {};
 1465|  5.43k|                }
 1466|  5.43k|            }
 1467|       |
 1468|       |            // Start building the set of keys involved in this node and children.
 1469|       |            // Start by keys in this node directly.
 1470|  5.43k|            size_t keys_count = node.keys.size();
 1471|  5.43k|            keyset key_set{node.keys.begin(), node.keys.end(), Comp(ctx)};
 1472|  5.43k|            if (key_set.size() != keys_count) {
 1473|       |                // It already has duplicates; bail out.
 1474|  5.43k|                node.has_duplicate_keys = true;
 1475|  5.43k|                return {};
 1476|  5.43k|            }
 1477|       |
 1478|       |            // Merge the keys from the children into this set.
 1479|  5.43k|            for (auto& sub : subs) {
 1480|  5.43k|                keys_count += sub->size();
 1481|       |                // Small optimization: std::set::merge is linear in the size of the second arg but
 1482|       |                // logarithmic in the size of the first.
 1483|  5.43k|                if (key_set.size() < sub->size()) std::swap(key_set, *sub);
 1484|  5.43k|                key_set.merge(*sub);
 1485|  5.43k|                if (key_set.size() != keys_count) {
 1486|  5.43k|                    node.has_duplicate_keys = true;
 1487|  5.43k|                    return {};
 1488|  5.43k|                }
 1489|  5.43k|            }
 1490|       |
 1491|  5.43k|            node.has_duplicate_keys = false;
 1492|  5.43k|            return key_set;
 1493|  5.43k|        };
 1494|       |
 1495|  5.43k|        TreeEval<state>(upfn);
 1496|  5.43k|    }
miniscript.cpp:_ZNK10miniscript4NodeI7CPubKeyE8TreeEvalINSt3__18optionalINS4_3setIS1_ZNKS2_17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS4_9allocatorIS1_EEEEEEZNKS7_IS9_EEvSC_EUlRKS2_4SpanISH_EE_EESA_T0_:
  699|  5.43k|    {
  700|  5.43k|        struct DummyState {};
  701|  5.43k|        return std::move(*TreeEvalMaybe<Result>(DummyState{},
  702|  5.43k|            [](DummyState, const Node&, size_t) { return DummyState{}; },
  703|  5.43k|            [&upfn](DummyState, const Node& node, Span<Result> subs) {
  704|  5.43k|                Result res{upfn(node, subs)};
  705|  5.43k|                return std::optional<Result>(std::move(res));
  706|  5.43k|            }
  707|  5.43k|        ));
  708|  5.43k|    }
miniscript.cpp:_ZNK10miniscript4NodeI7CPubKeyE13TreeEvalMaybeINSt3__18optionalINS4_3setIS1_ZNKS2_17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS4_9allocatorIS1_EEEEEEZNKS2_8TreeEvalISH_ZNKS7_IS9_EEvSC_EUlRKS2_4SpanISH_EE_EESA_T0_E10DummyStateZNKSI_ISH_SN_EESA_SO_EUlSP_SK_mE_ZNKSI_ISH_SN_EESA_SO_EUlSP_SK_SM_E_EENS5_ISA_EESO_T1_T2_:
  605|  5.43k|    {
  606|       |        /** Entries of the explicit stack tracked in this algorithm. */
  607|  5.43k|        struct StackElem
  608|  5.43k|        {
  609|  5.43k|            const Node& node; //!< The node being evaluated.
  610|  5.43k|            size_t expanded; //!< How many children of this node have been expanded.
  611|  5.43k|            State state; //!< The state for that node.
  612|       |
  613|  5.43k|            StackElem(const Node& node_, size_t exp_, State&& state_) :
  614|  5.43k|                node(node_), expanded(exp_), state(std::move(state_)) {}
  615|  5.43k|        };
  616|       |        /* Stack of tree nodes being explored. */
  617|  5.43k|        std::vector<StackElem> stack;
  618|       |        /* Results of subtrees so far. Their order and mapping to tree nodes
  619|       |         * is implicitly defined by stack. */
  620|  5.43k|        std::vector<Result> results;
  621|  5.43k|        stack.emplace_back(*this, 0, std::move(root_state));
  622|       |
  623|       |        /* Here is a demonstration of the algorithm, for an example tree A(B,C(D,E),F).
  624|       |         * State variables are omitted for simplicity.
  625|       |         *
  626|       |         * First: stack=[(A,0)] results=[]
  627|       |         *        stack=[(A,1),(B,0)] results=[]
  628|       |         *        stack=[(A,1)] results=[B]
  629|       |         *        stack=[(A,2),(C,0)] results=[B]
  630|       |         *        stack=[(A,2),(C,1),(D,0)] results=[B]
  631|       |         *        stack=[(A,2),(C,1)] results=[B,D]
  632|       |         *        stack=[(A,2),(C,2),(E,0)] results=[B,D]
  633|       |         *        stack=[(A,2),(C,2)] results=[B,D,E]
  634|       |         *        stack=[(A,2)] results=[B,C]
  635|       |         *        stack=[(A,3),(F,0)] results=[B,C]
  636|       |         *        stack=[(A,3)] results=[B,C,F]
  637|       |         * Final: stack=[] results=[A]
  638|       |         */
  639|  55.3M|        while (stack.size()) {
  ------------------
  |  Branch (639:16): [True: 55.3M, False: 5.43k]
  ------------------
  640|  55.3M|            const Node& node = stack.back().node;
  641|  55.3M|            if (stack.back().expanded < node.subs.size()) {
  ------------------
  |  Branch (641:17): [True: 27.6M, False: 27.6M]
  ------------------
  642|       |                /* We encounter a tree node with at least one unexpanded child.
  643|       |                 * Expand it. By the time we hit this node again, the result of
  644|       |                 * that child (and all earlier children) will be at the end of `results`. */
  645|  27.6M|                size_t child_index = stack.back().expanded++;
  646|  27.6M|                State child_state = downfn(stack.back().state, node, child_index);
  647|  27.6M|                stack.emplace_back(*node.subs[child_index], 0, std::move(child_state));
  648|  27.6M|                continue;
  649|  27.6M|            }
  650|       |            // Invoke upfn with the last node.subs.size() elements of results as input.
  651|  27.6M|            assert(results.size() >= node.subs.size());
  652|  27.6M|            std::optional<Result> result{upfn(std::move(stack.back().state), node,
  653|  27.6M|                Span<Result>{results}.last(node.subs.size()))};
  654|       |            // If evaluation returns std::nullopt, abort immediately.
  655|  27.6M|            if (!result) return {};
  ------------------
  |  Branch (655:17): [True: 0, False: 27.6M]
  ------------------
  656|       |            // Replace the last node.subs.size() elements of results with the new result.
  657|  27.6M|            results.erase(results.end() - node.subs.size(), results.end());
  658|  27.6M|            results.push_back(std::move(*result));
  659|  27.6M|            stack.pop_back();
  660|  27.6M|        }
  661|       |        // The final remaining results element is the root result, return it.
  662|  5.43k|        assert(results.size() == 1);
  663|  5.43k|        return std::move(results[0]);
  664|  5.43k|    }
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE13TreeEvalMaybeINSt3__18optionalINS4_3setIS1_ZNKS2_17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS4_9allocatorIS1_EEEEEEZNKS2_8TreeEvalISH_ZNKS7_IS9_EEvSC_EUlRKS2_4SpanISH_EE_EESA_T0_E10DummyStateZNKSI_ISH_SN_EESA_SO_EUlSP_SK_mE_ZNKSI_ISH_SN_EESA_SO_EUlSP_SK_SM_E_EENS5_ISA_EESO_T1_T2_EN9StackElemC2ESK_mOSP_:
  614|  27.6M|                node(node_), expanded(exp_), state(std::move(state_)) {}
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE8TreeEvalINSt3__18optionalINS4_3setIS1_ZNKS2_17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS4_9allocatorIS1_EEEEEEZNKS7_IS9_EEvSC_EUlRKS2_4SpanISH_EE_EESA_T0_ENKUlZNKS3_ISH_SM_EESA_SN_E10DummyStateSJ_mE_clESO_SJ_m:
  702|  27.6M|            [](DummyState, const Node&, size_t) { return DummyState{}; },
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE8TreeEvalINSt3__18optionalINS4_3setIS1_ZNKS2_17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS4_9allocatorIS1_EEEEEEZNKS7_IS9_EEvSC_EUlRKS2_4SpanISH_EE_EESA_T0_ENKUlZNKS3_ISH_SM_EESA_SN_E10DummyStateSJ_SL_E_clESO_SJ_SL_:
  703|  27.6M|            [&upfn](DummyState, const Node& node, Span<Result> subs) {
  704|  27.6M|                Result res{upfn(node, subs)};
  705|  27.6M|                return std::optional<Result>(std::move(res));
  706|  27.6M|            }
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_ENKUlRKS2_4SpanINSt3__18optionalINSC_3setIS1_ZNKS3_IS5_EEvS8_E4CompNSC_9allocatorIS1_EEEEEEEE_clESA_SK_:
 1456|  27.6M|        auto upfn = [&ctx](const Node& node, Span<state> subs) -> state {
 1457|       |            // If this node is already known to have duplicates, nothing left to do.
 1458|  27.6M|            if (node.has_duplicate_keys.has_value() && *node.has_duplicate_keys) return {};
  ------------------
  |  Branch (1458:17): [True: 0, False: 27.6M]
  |  Branch (1458:56): [True: 0, False: 0]
  ------------------
 1459|       |
 1460|       |            // Check if one of the children is already known to have duplicates.
 1461|  27.6M|            for (auto& sub : subs) {
  ------------------
  |  Branch (1461:28): [True: 27.6M, False: 27.2M]
  ------------------
 1462|  27.6M|                if (!sub.has_value()) {
  ------------------
  |  Branch (1462:21): [True: 477k, False: 27.1M]
  ------------------
 1463|   477k|                    node.has_duplicate_keys = true;
 1464|   477k|                    return {};
 1465|   477k|                }
 1466|  27.6M|            }
 1467|       |
 1468|       |            // Start building the set of keys involved in this node and children.
 1469|       |            // Start by keys in this node directly.
 1470|  27.2M|            size_t keys_count = node.keys.size();
 1471|  27.2M|            keyset key_set{node.keys.begin(), node.keys.end(), Comp(ctx)};
 1472|  27.2M|            if (key_set.size() != keys_count) {
  ------------------
  |  Branch (1472:17): [True: 2.06k, False: 27.2M]
  ------------------
 1473|       |                // It already has duplicates; bail out.
 1474|  2.06k|                node.has_duplicate_keys = true;
 1475|  2.06k|                return {};
 1476|  2.06k|            }
 1477|       |
 1478|       |            // Merge the keys from the children into this set.
 1479|  27.2M|            for (auto& sub : subs) {
  ------------------
  |  Branch (1479:28): [True: 27.0M, False: 27.2M]
  ------------------
 1480|  27.0M|                keys_count += sub->size();
 1481|       |                // Small optimization: std::set::merge is linear in the size of the second arg but
 1482|       |                // logarithmic in the size of the first.
 1483|  27.0M|                if (key_set.size() < sub->size()) std::swap(key_set, *sub);
  ------------------
  |  Branch (1483:21): [True: 1.58M, False: 25.5M]
  ------------------
 1484|  27.0M|                key_set.merge(*sub);
 1485|  27.0M|                if (key_set.size() != keys_count) {
  ------------------
  |  Branch (1485:21): [True: 4.57k, False: 27.0M]
  ------------------
 1486|  4.57k|                    node.has_duplicate_keys = true;
 1487|  4.57k|                    return {};
 1488|  4.57k|                }
 1489|  27.0M|            }
 1490|       |
 1491|  27.2M|            node.has_duplicate_keys = false;
 1492|  27.2M|            return key_set;
 1493|  27.2M|        };
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_EN4CompC2ERKS5_:
 1446|  27.2M|            Comp(const Ctx& ctx) : ctx_ptr(&ctx) {}
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_ENK4CompclERKS1_SB_:
 1447|   435k|            bool operator()(const Key& a, const Key& b) const { return ctx_ptr->KeyCompare(a, b); }
miniscript.cpp:_ZNK10miniscript4NodeI7CPubKeyE8ToStringIN12_GLOBAL__N_113ParserContextEEENSt3__18optionalINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEEERKT_:
  829|  2.71k|    std::optional<std::string> ToString(const CTx& ctx) const {
  830|       |        // To construct the std::string representation for a Miniscript object, we use
  831|       |        // the TreeEvalMaybe algorithm. The State is a boolean: whether the parent node is a
  832|       |        // wrapper. If so, non-wrapper expressions must be prefixed with a ":".
  833|  2.71k|        auto downfn = [](bool, const Node& node, size_t) {
  834|  2.71k|            return (node.fragment == Fragment::WRAP_A || node.fragment == Fragment::WRAP_S ||
  835|  2.71k|                    node.fragment == Fragment::WRAP_D || node.fragment == Fragment::WRAP_V ||
  836|  2.71k|                    node.fragment == Fragment::WRAP_J || node.fragment == Fragment::WRAP_N ||
  837|  2.71k|                    node.fragment == Fragment::WRAP_C ||
  838|  2.71k|                    (node.fragment == Fragment::AND_V && node.subs[1]->fragment == Fragment::JUST_1) ||
  839|  2.71k|                    (node.fragment == Fragment::OR_I && node.subs[0]->fragment == Fragment::JUST_0) ||
  840|  2.71k|                    (node.fragment == Fragment::OR_I && node.subs[1]->fragment == Fragment::JUST_0));
  841|  2.71k|        };
  842|       |        // The upward function computes for a node, given whether its parent is a wrapper,
  843|       |        // and the string representations of its child nodes, the string representation of the node.
  844|  2.71k|        const bool is_tapscript{IsTapscript(m_script_ctx)};
  845|  2.71k|        auto upfn = [&ctx, is_tapscript](bool wrapped, const Node& node, Span<std::string> subs) -> std::optional<std::string> {
  846|  2.71k|            std::string ret = wrapped ? ":" : "";
  847|       |
  848|  2.71k|            switch (node.fragment) {
  849|  2.71k|                case Fragment::WRAP_A: return "a" + std::move(subs[0]);
  850|  2.71k|                case Fragment::WRAP_S: return "s" + std::move(subs[0]);
  851|  2.71k|                case Fragment::WRAP_C:
  852|  2.71k|                    if (node.subs[0]->fragment == Fragment::PK_K) {
  853|       |                        // pk(K) is syntactic sugar for c:pk_k(K)
  854|  2.71k|                        auto key_str = ctx.ToString(node.subs[0]->keys[0]);
  855|  2.71k|                        if (!key_str) return {};
  856|  2.71k|                        return std::move(ret) + "pk(" + std::move(*key_str) + ")";
  857|  2.71k|                    }
  858|  2.71k|                    if (node.subs[0]->fragment == Fragment::PK_H) {
  859|       |                        // pkh(K) is syntactic sugar for c:pk_h(K)
  860|  2.71k|                        auto key_str = ctx.ToString(node.subs[0]->keys[0]);
  861|  2.71k|                        if (!key_str) return {};
  862|  2.71k|                        return std::move(ret) + "pkh(" + std::move(*key_str) + ")";
  863|  2.71k|                    }
  864|  2.71k|                    return "c" + std::move(subs[0]);
  865|  2.71k|                case Fragment::WRAP_D: return "d" + std::move(subs[0]);
  866|  2.71k|                case Fragment::WRAP_V: return "v" + std::move(subs[0]);
  867|  2.71k|                case Fragment::WRAP_J: return "j" + std::move(subs[0]);
  868|  2.71k|                case Fragment::WRAP_N: return "n" + std::move(subs[0]);
  869|  2.71k|                case Fragment::AND_V:
  870|       |                    // t:X is syntactic sugar for and_v(X,1).
  871|  2.71k|                    if (node.subs[1]->fragment == Fragment::JUST_1) return "t" + std::move(subs[0]);
  872|  2.71k|                    break;
  873|  2.71k|                case Fragment::OR_I:
  874|  2.71k|                    if (node.subs[0]->fragment == Fragment::JUST_0) return "l" + std::move(subs[1]);
  875|  2.71k|                    if (node.subs[1]->fragment == Fragment::JUST_0) return "u" + std::move(subs[0]);
  876|  2.71k|                    break;
  877|  2.71k|                default: break;
  878|  2.71k|            }
  879|  2.71k|            switch (node.fragment) {
  880|  2.71k|                case Fragment::PK_K: {
  881|  2.71k|                    auto key_str = ctx.ToString(node.keys[0]);
  882|  2.71k|                    if (!key_str) return {};
  883|  2.71k|                    return std::move(ret) + "pk_k(" + std::move(*key_str) + ")";
  884|  2.71k|                }
  885|  2.71k|                case Fragment::PK_H: {
  886|  2.71k|                    auto key_str = ctx.ToString(node.keys[0]);
  887|  2.71k|                    if (!key_str) return {};
  888|  2.71k|                    return std::move(ret) + "pk_h(" + std::move(*key_str) + ")";
  889|  2.71k|                }
  890|  2.71k|                case Fragment::AFTER: return std::move(ret) + "after(" + util::ToString(node.k) + ")";
  891|  2.71k|                case Fragment::OLDER: return std::move(ret) + "older(" + util::ToString(node.k) + ")";
  892|  2.71k|                case Fragment::HASH256: return std::move(ret) + "hash256(" + HexStr(node.data) + ")";
  893|  2.71k|                case Fragment::HASH160: return std::move(ret) + "hash160(" + HexStr(node.data) + ")";
  894|  2.71k|                case Fragment::SHA256: return std::move(ret) + "sha256(" + HexStr(node.data) + ")";
  895|  2.71k|                case Fragment::RIPEMD160: return std::move(ret) + "ripemd160(" + HexStr(node.data) + ")";
  896|  2.71k|                case Fragment::JUST_1: return std::move(ret) + "1";
  897|  2.71k|                case Fragment::JUST_0: return std::move(ret) + "0";
  898|  2.71k|                case Fragment::AND_V: return std::move(ret) + "and_v(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  899|  2.71k|                case Fragment::AND_B: return std::move(ret) + "and_b(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  900|  2.71k|                case Fragment::OR_B: return std::move(ret) + "or_b(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  901|  2.71k|                case Fragment::OR_D: return std::move(ret) + "or_d(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  902|  2.71k|                case Fragment::OR_C: return std::move(ret) + "or_c(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  903|  2.71k|                case Fragment::OR_I: return std::move(ret) + "or_i(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  904|  2.71k|                case Fragment::ANDOR:
  905|       |                    // and_n(X,Y) is syntactic sugar for andor(X,Y,0).
  906|  2.71k|                    if (node.subs[2]->fragment == Fragment::JUST_0) return std::move(ret) + "and_n(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  907|  2.71k|                    return std::move(ret) + "andor(" + std::move(subs[0]) + "," + std::move(subs[1]) + "," + std::move(subs[2]) + ")";
  908|  2.71k|                case Fragment::MULTI: {
  909|  2.71k|                    CHECK_NONFATAL(!is_tapscript);
  910|  2.71k|                    auto str = std::move(ret) + "multi(" + util::ToString(node.k);
  911|  2.71k|                    for (const auto& key : node.keys) {
  912|  2.71k|                        auto key_str = ctx.ToString(key);
  913|  2.71k|                        if (!key_str) return {};
  914|  2.71k|                        str += "," + std::move(*key_str);
  915|  2.71k|                    }
  916|  2.71k|                    return std::move(str) + ")";
  917|  2.71k|                }
  918|  2.71k|                case Fragment::MULTI_A: {
  919|  2.71k|                    CHECK_NONFATAL(is_tapscript);
  920|  2.71k|                    auto str = std::move(ret) + "multi_a(" + util::ToString(node.k);
  921|  2.71k|                    for (const auto& key : node.keys) {
  922|  2.71k|                        auto key_str = ctx.ToString(key);
  923|  2.71k|                        if (!key_str) return {};
  924|  2.71k|                        str += "," + std::move(*key_str);
  925|  2.71k|                    }
  926|  2.71k|                    return std::move(str) + ")";
  927|  2.71k|                }
  928|  2.71k|                case Fragment::THRESH: {
  929|  2.71k|                    auto str = std::move(ret) + "thresh(" + util::ToString(node.k);
  930|  2.71k|                    for (auto& sub : subs) {
  931|  2.71k|                        str += "," + std::move(sub);
  932|  2.71k|                    }
  933|  2.71k|                    return std::move(str) + ")";
  934|  2.71k|                }
  935|  2.71k|                default: break;
  936|  2.71k|            }
  937|  2.71k|            assert(false);
  938|  2.71k|        };
  939|       |
  940|  2.71k|        return TreeEvalMaybe<std::string>(false, downfn, upfn);
  941|  2.71k|    }
miniscript.cpp:_ZNK10miniscript4NodeI7CPubKeyE13TreeEvalMaybeINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEbZNKS2_8ToStringIN12_GLOBAL__N_113ParserContextEEENS4_8optionalISA_EERKT_EUlbRKS2_mE_ZNKSB_ISD_EESF_SI_EUlbSK_4SpanISA_EE_EENSE_ISG_EET0_T1_T2_:
  605|  2.71k|    {
  606|       |        /** Entries of the explicit stack tracked in this algorithm. */
  607|  2.71k|        struct StackElem
  608|  2.71k|        {
  609|  2.71k|            const Node& node; //!< The node being evaluated.
  610|  2.71k|            size_t expanded; //!< How many children of this node have been expanded.
  611|  2.71k|            State state; //!< The state for that node.
  612|       |
  613|  2.71k|            StackElem(const Node& node_, size_t exp_, State&& state_) :
  614|  2.71k|                node(node_), expanded(exp_), state(std::move(state_)) {}
  615|  2.71k|        };
  616|       |        /* Stack of tree nodes being explored. */
  617|  2.71k|        std::vector<StackElem> stack;
  618|       |        /* Results of subtrees so far. Their order and mapping to tree nodes
  619|       |         * is implicitly defined by stack. */
  620|  2.71k|        std::vector<Result> results;
  621|  2.71k|        stack.emplace_back(*this, 0, std::move(root_state));
  622|       |
  623|       |        /* Here is a demonstration of the algorithm, for an example tree A(B,C(D,E),F).
  624|       |         * State variables are omitted for simplicity.
  625|       |         *
  626|       |         * First: stack=[(A,0)] results=[]
  627|       |         *        stack=[(A,1),(B,0)] results=[]
  628|       |         *        stack=[(A,1)] results=[B]
  629|       |         *        stack=[(A,2),(C,0)] results=[B]
  630|       |         *        stack=[(A,2),(C,1),(D,0)] results=[B]
  631|       |         *        stack=[(A,2),(C,1)] results=[B,D]
  632|       |         *        stack=[(A,2),(C,2),(E,0)] results=[B,D]
  633|       |         *        stack=[(A,2),(C,2)] results=[B,D,E]
  634|       |         *        stack=[(A,2)] results=[B,C]
  635|       |         *        stack=[(A,3),(F,0)] results=[B,C]
  636|       |         *        stack=[(A,3)] results=[B,C,F]
  637|       |         * Final: stack=[] results=[A]
  638|       |         */
  639|  27.6M|        while (stack.size()) {
  ------------------
  |  Branch (639:16): [True: 27.6M, False: 2.71k]
  ------------------
  640|  27.6M|            const Node& node = stack.back().node;
  641|  27.6M|            if (stack.back().expanded < node.subs.size()) {
  ------------------
  |  Branch (641:17): [True: 13.8M, False: 13.8M]
  ------------------
  642|       |                /* We encounter a tree node with at least one unexpanded child.
  643|       |                 * Expand it. By the time we hit this node again, the result of
  644|       |                 * that child (and all earlier children) will be at the end of `results`. */
  645|  13.8M|                size_t child_index = stack.back().expanded++;
  646|  13.8M|                State child_state = downfn(stack.back().state, node, child_index);
  647|  13.8M|                stack.emplace_back(*node.subs[child_index], 0, std::move(child_state));
  648|  13.8M|                continue;
  649|  13.8M|            }
  650|       |            // Invoke upfn with the last node.subs.size() elements of results as input.
  651|  13.8M|            assert(results.size() >= node.subs.size());
  652|  13.8M|            std::optional<Result> result{upfn(std::move(stack.back().state), node,
  653|  13.8M|                Span<Result>{results}.last(node.subs.size()))};
  654|       |            // If evaluation returns std::nullopt, abort immediately.
  655|  13.8M|            if (!result) return {};
  ------------------
  |  Branch (655:17): [True: 0, False: 13.8M]
  ------------------
  656|       |            // Replace the last node.subs.size() elements of results with the new result.
  657|  13.8M|            results.erase(results.end() - node.subs.size(), results.end());
  658|  13.8M|            results.push_back(std::move(*result));
  659|  13.8M|            stack.pop_back();
  660|  13.8M|        }
  661|       |        // The final remaining results element is the root result, return it.
  662|  2.71k|        assert(results.size() == 1);
  663|  2.71k|        return std::move(results[0]);
  664|  2.71k|    }
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE13TreeEvalMaybeINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEbZNKS2_8ToStringIN12_GLOBAL__N_113ParserContextEEENS4_8optionalISA_EERKT_EUlbRKS2_mE_ZNKSB_ISD_EESF_SI_EUlbSK_4SpanISA_EE_EENSE_ISG_EET0_T1_T2_EN9StackElemC2ESK_mOb:
  614|  13.8M|                node(node_), expanded(exp_), state(std::move(state_)) {}
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE8ToStringIN12_GLOBAL__N_113ParserContextEEENSt3__18optionalINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEEERKT_ENKUlbRKS2_mE_clEbSJ_m:
  833|  13.8M|        auto downfn = [](bool, const Node& node, size_t) {
  834|  13.8M|            return (node.fragment == Fragment::WRAP_A || node.fragment == Fragment::WRAP_S ||
  ------------------
  |  Branch (834:21): [True: 144k, False: 13.6M]
  |  Branch (834:58): [True: 73.7k, False: 13.6M]
  ------------------
  835|  13.8M|                    node.fragment == Fragment::WRAP_D || node.fragment == Fragment::WRAP_V ||
  ------------------
  |  Branch (835:21): [True: 81.4k, False: 13.5M]
  |  Branch (835:58): [True: 39.0k, False: 13.5M]
  ------------------
  836|  13.8M|                    node.fragment == Fragment::WRAP_J || node.fragment == Fragment::WRAP_N ||
  ------------------
  |  Branch (836:21): [True: 50.6k, False: 13.4M]
  |  Branch (836:58): [True: 145k, False: 13.3M]
  ------------------
  837|  13.8M|                    node.fragment == Fragment::WRAP_C ||
  ------------------
  |  Branch (837:21): [True: 2.26M, False: 11.0M]
  ------------------
  838|  13.8M|                    (node.fragment == Fragment::AND_V && node.subs[1]->fragment == Fragment::JUST_1) ||
  ------------------
  |  Branch (838:22): [True: 6.59M, False: 4.44M]
  |  Branch (838:58): [True: 6.59M, False: 1.55k]
  ------------------
  839|  13.8M|                    (node.fragment == Fragment::OR_I && node.subs[0]->fragment == Fragment::JUST_0) ||
  ------------------
  |  Branch (839:22): [True: 4.35M, False: 89.8k]
  |  Branch (839:57): [True: 3.15M, False: 1.20M]
  ------------------
  840|  13.8M|                    (node.fragment == Fragment::OR_I && node.subs[1]->fragment == Fragment::JUST_0));
  ------------------
  |  Branch (840:22): [True: 1.20M, False: 89.8k]
  |  Branch (840:57): [True: 1.18M, False: 14.8k]
  ------------------
  841|  13.8M|        };
miniscript.cpp:_ZZNK10miniscript4NodeI7CPubKeyE8ToStringIN12_GLOBAL__N_113ParserContextEEENSt3__18optionalINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEEERKT_ENKUlbRKS2_4SpanISD_EE_clEbSJ_SL_:
  845|  13.8M|        auto upfn = [&ctx, is_tapscript](bool wrapped, const Node& node, Span<std::string> subs) -> std::optional<std::string> {
  846|  13.8M|            std::string ret = wrapped ? ":" : "";
  ------------------
  |  Branch (846:31): [True: 13.7M, False: 107k]
  ------------------
  847|       |
  848|  13.8M|            switch (node.fragment) {
  849|   144k|                case Fragment::WRAP_A: return "a" + std::move(subs[0]);
  ------------------
  |  Branch (849:17): [True: 144k, False: 13.7M]
  ------------------
  850|  73.7k|                case Fragment::WRAP_S: return "s" + std::move(subs[0]);
  ------------------
  |  Branch (850:17): [True: 73.7k, False: 13.7M]
  ------------------
  851|  2.26M|                case Fragment::WRAP_C:
  ------------------
  |  Branch (851:17): [True: 2.26M, False: 11.5M]
  ------------------
  852|  2.26M|                    if (node.subs[0]->fragment == Fragment::PK_K) {
  ------------------
  |  Branch (852:25): [True: 8.55k, False: 2.25M]
  ------------------
  853|       |                        // pk(K) is syntactic sugar for c:pk_k(K)
  854|  8.55k|                        auto key_str = ctx.ToString(node.subs[0]->keys[0]);
  855|  8.55k|                        if (!key_str) return {};
  ------------------
  |  Branch (855:29): [True: 0, False: 8.55k]
  ------------------
  856|  8.55k|                        return std::move(ret) + "pk(" + std::move(*key_str) + ")";
  857|  8.55k|                    }
  858|  2.25M|                    if (node.subs[0]->fragment == Fragment::PK_H) {
  ------------------
  |  Branch (858:25): [True: 3.70k, False: 2.25M]
  ------------------
  859|       |                        // pkh(K) is syntactic sugar for c:pk_h(K)
  860|  3.70k|                        auto key_str = ctx.ToString(node.subs[0]->keys[0]);
  861|  3.70k|                        if (!key_str) return {};
  ------------------
  |  Branch (861:29): [True: 0, False: 3.70k]
  ------------------
  862|  3.70k|                        return std::move(ret) + "pkh(" + std::move(*key_str) + ")";
  863|  3.70k|                    }
  864|  2.25M|                    return "c" + std::move(subs[0]);
  865|  81.4k|                case Fragment::WRAP_D: return "d" + std::move(subs[0]);
  ------------------
  |  Branch (865:17): [True: 81.4k, False: 13.7M]
  ------------------
  866|  39.0k|                case Fragment::WRAP_V: return "v" + std::move(subs[0]);
  ------------------
  |  Branch (866:17): [True: 39.0k, False: 13.8M]
  ------------------
  867|  50.6k|                case Fragment::WRAP_J: return "j" + std::move(subs[0]);
  ------------------
  |  Branch (867:17): [True: 50.6k, False: 13.7M]
  ------------------
  868|   145k|                case Fragment::WRAP_N: return "n" + std::move(subs[0]);
  ------------------
  |  Branch (868:17): [True: 145k, False: 13.7M]
  ------------------
  869|  3.29M|                case Fragment::AND_V:
  ------------------
  |  Branch (869:17): [True: 3.29M, False: 10.5M]
  ------------------
  870|       |                    // t:X is syntactic sugar for and_v(X,1).
  871|  3.29M|                    if (node.subs[1]->fragment == Fragment::JUST_1) return "t" + std::move(subs[0]);
  ------------------
  |  Branch (871:25): [True: 3.29M, False: 776]
  ------------------
  872|    776|                    break;
  873|  2.17M|                case Fragment::OR_I:
  ------------------
  |  Branch (873:17): [True: 2.17M, False: 11.6M]
  ------------------
  874|  2.17M|                    if (node.subs[0]->fragment == Fragment::JUST_0) return "l" + std::move(subs[1]);
  ------------------
  |  Branch (874:25): [True: 1.57M, False: 601k]
  ------------------
  875|   601k|                    if (node.subs[1]->fragment == Fragment::JUST_0) return "u" + std::move(subs[0]);
  ------------------
  |  Branch (875:25): [True: 593k, False: 7.44k]
  ------------------
  876|  7.44k|                    break;
  877|  5.56M|                default: break;
  ------------------
  |  Branch (877:17): [True: 5.56M, False: 8.27M]
  ------------------
  878|  13.8M|            }
  879|  5.57M|            switch (node.fragment) {
  880|  8.69k|                case Fragment::PK_K: {
  ------------------
  |  Branch (880:17): [True: 8.69k, False: 5.56M]
  ------------------
  881|  8.69k|                    auto key_str = ctx.ToString(node.keys[0]);
  882|  8.69k|                    if (!key_str) return {};
  ------------------
  |  Branch (882:25): [True: 0, False: 8.69k]
  ------------------
  883|  8.69k|                    return std::move(ret) + "pk_k(" + std::move(*key_str) + ")";
  884|  8.69k|                }
  885|  8.92k|                case Fragment::PK_H: {
  ------------------
  |  Branch (885:17): [True: 8.92k, False: 5.56M]
  ------------------
  886|  8.92k|                    auto key_str = ctx.ToString(node.keys[0]);
  887|  8.92k|                    if (!key_str) return {};
  ------------------
  |  Branch (887:25): [True: 0, False: 8.92k]
  ------------------
  888|  8.92k|                    return std::move(ret) + "pk_h(" + std::move(*key_str) + ")";
  889|  8.92k|                }
  890|  1.94k|                case Fragment::AFTER: return std::move(ret) + "after(" + util::ToString(node.k) + ")";
  ------------------
  |  Branch (890:17): [True: 1.94k, False: 5.57M]
  ------------------
  891|  4.34k|                case Fragment::OLDER: return std::move(ret) + "older(" + util::ToString(node.k) + ")";
  ------------------
  |  Branch (891:17): [True: 4.34k, False: 5.57M]
  ------------------
  892|    103|                case Fragment::HASH256: return std::move(ret) + "hash256(" + HexStr(node.data) + ")";
  ------------------
  |  Branch (892:17): [True: 103, False: 5.57M]
  ------------------
  893|    271|                case Fragment::HASH160: return std::move(ret) + "hash160(" + HexStr(node.data) + ")";
  ------------------
  |  Branch (893:17): [True: 271, False: 5.57M]
  ------------------
  894|    128|                case Fragment::SHA256: return std::move(ret) + "sha256(" + HexStr(node.data) + ")";
  ------------------
  |  Branch (894:17): [True: 128, False: 5.57M]
  ------------------
  895|    425|                case Fragment::RIPEMD160: return std::move(ret) + "ripemd160(" + HexStr(node.data) + ")";
  ------------------
  |  Branch (895:17): [True: 425, False: 5.57M]
  ------------------
  896|  3.32M|                case Fragment::JUST_1: return std::move(ret) + "1";
  ------------------
  |  Branch (896:17): [True: 3.32M, False: 2.25M]
  ------------------
  897|  2.19M|                case Fragment::JUST_0: return std::move(ret) + "0";
  ------------------
  |  Branch (897:17): [True: 2.19M, False: 3.37M]
  ------------------
  898|    776|                case Fragment::AND_V: return std::move(ret) + "and_v(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  ------------------
  |  Branch (898:17): [True: 776, False: 5.57M]
  ------------------
  899|  2.98k|                case Fragment::AND_B: return std::move(ret) + "and_b(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  ------------------
  |  Branch (899:17): [True: 2.98k, False: 5.57M]
  ------------------
  900|  1.87k|                case Fragment::OR_B: return std::move(ret) + "or_b(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  ------------------
  |  Branch (900:17): [True: 1.87k, False: 5.57M]
  ------------------
  901|  2.06k|                case Fragment::OR_D: return std::move(ret) + "or_d(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  ------------------
  |  Branch (901:17): [True: 2.06k, False: 5.57M]
  ------------------
  902|  1.46k|                case Fragment::OR_C: return std::move(ret) + "or_c(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  ------------------
  |  Branch (902:17): [True: 1.46k, False: 5.57M]
  ------------------
  903|  7.44k|                case Fragment::OR_I: return std::move(ret) + "or_i(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  ------------------
  |  Branch (903:17): [True: 7.44k, False: 5.56M]
  ------------------
  904|  3.88k|                case Fragment::ANDOR:
  ------------------
  |  Branch (904:17): [True: 3.88k, False: 5.57M]
  ------------------
  905|       |                    // and_n(X,Y) is syntactic sugar for andor(X,Y,0).
  906|  3.88k|                    if (node.subs[2]->fragment == Fragment::JUST_0) return std::move(ret) + "and_n(" + std::move(subs[0]) + "," + std::move(subs[1]) + ")";
  ------------------
  |  Branch (906:25): [True: 1.36k, False: 2.52k]
  ------------------
  907|  2.52k|                    return std::move(ret) + "andor(" + std::move(subs[0]) + "," + std::move(subs[1]) + "," + std::move(subs[2]) + ")";
  908|  1.22k|                case Fragment::MULTI: {
  ------------------
  |  Branch (908:17): [True: 1.22k, False: 5.57M]
  ------------------
  909|  1.22k|                    CHECK_NONFATAL(!is_tapscript);
  ------------------
  |  |   82|  1.22k|    inline_check_non_fatal(condition, __FILE__, __LINE__, __func__, #condition)
  ------------------
  910|  1.22k|                    auto str = std::move(ret) + "multi(" + util::ToString(node.k);
  911|  8.03k|                    for (const auto& key : node.keys) {
  ------------------
  |  Branch (911:42): [True: 8.03k, False: 1.22k]
  ------------------
  912|  8.03k|                        auto key_str = ctx.ToString(key);
  913|  8.03k|                        if (!key_str) return {};
  ------------------
  |  Branch (913:29): [True: 0, False: 8.03k]
  ------------------
  914|  8.03k|                        str += "," + std::move(*key_str);
  915|  8.03k|                    }
  916|  1.22k|                    return std::move(str) + ")";
  917|  1.22k|                }
  918|  2.11k|                case Fragment::MULTI_A: {
  ------------------
  |  Branch (918:17): [True: 2.11k, False: 5.57M]
  ------------------
  919|  2.11k|                    CHECK_NONFATAL(is_tapscript);
  ------------------
  |  |   82|  2.11k|    inline_check_non_fatal(condition, __FILE__, __LINE__, __func__, #condition)
  ------------------
  920|  2.11k|                    auto str = std::move(ret) + "multi_a(" + util::ToString(node.k);
  921|  26.6k|                    for (const auto& key : node.keys) {
  ------------------
  |  Branch (921:42): [True: 26.6k, False: 2.11k]
  ------------------
  922|  26.6k|                        auto key_str = ctx.ToString(key);
  923|  26.6k|                        if (!key_str) return {};
  ------------------
  |  Branch (923:29): [True: 0, False: 26.6k]
  ------------------
  924|  26.6k|                        str += "," + std::move(*key_str);
  925|  26.6k|                    }
  926|  2.11k|                    return std::move(str) + ")";
  927|  2.11k|                }
  928|  2.79k|                case Fragment::THRESH: {
  ------------------
  |  Branch (928:17): [True: 2.79k, False: 5.57M]
  ------------------
  929|  2.79k|                    auto str = std::move(ret) + "thresh(" + util::ToString(node.k);
  930|  59.8k|                    for (auto& sub : subs) {
  ------------------
  |  Branch (930:36): [True: 59.8k, False: 2.79k]
  ------------------
  931|  59.8k|                        str += "," + std::move(sub);
  932|  59.8k|                    }
  933|  2.79k|                    return std::move(str) + ")";
  934|  2.11k|                }
  935|      0|                default: break;
  ------------------
  |  Branch (935:17): [True: 0, False: 5.57M]
  ------------------
  936|  5.57M|            }
  937|      0|            assert(false);
  938|      0|        };
miniscript.cpp:_ZN10miniscript10FromStringIN12_GLOBAL__N_113ParserContextEEENSt3__110unique_ptrIKNS_4NodeINT_3KeyEEENS3_14default_deleteIS9_EEEERKNS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKS6_:
 2640|  8.19k|inline NodeRef<typename Ctx::Key> FromString(const std::string& str, const Ctx& ctx) {
 2641|  8.19k|    return internal::Parse<typename Ctx::Key>(str, ctx);
 2642|  8.19k|}
miniscript.cpp:_ZN10miniscript8internal5ParseI7CPubKeyN12_GLOBAL__N_113ParserContextEEENSt3__110unique_ptrIKNS_4NodeIT_EENS5_14default_deleteISA_EEEE4SpanIKcERKT0_:
 1794|  8.19k|{
 1795|  8.19k|    using namespace script;
 1796|       |
 1797|       |    // Account for the minimum script size for all parsed fragments so far. It "borrows" 1
 1798|       |    // script byte from all leaf nodes, counting it instead whenever a space for a recursive
 1799|       |    // expression is added (through andor, and_*, or_*, thresh). This guarantees that all fragments
 1800|       |    // increment the script_size by at least one, except for:
 1801|       |    // - "0", "1": these leafs are only a single byte, so their subtracted-from increment is 0.
 1802|       |    //   This is not an issue however, as "space" for them has to be created by combinators,
 1803|       |    //   which do increment script_size.
 1804|       |    // - "v:": the v wrapper adds nothing as in some cases it results in no opcode being added
 1805|       |    //   (instead transforming another opcode into its VERIFY form). However, the v: wrapper has
 1806|       |    //   to be interleaved with other fragments to be valid, so this is not a concern.
 1807|  8.19k|    size_t script_size{1};
 1808|  8.19k|    size_t max_size{internal::MaxScriptSize(ctx.MsContext())};
 1809|       |
 1810|       |    // The two integers are used to hold state for thresh()
 1811|  8.19k|    std::vector<std::tuple<ParseContext, int64_t, int64_t>> to_parse;
 1812|  8.19k|    std::vector<NodeRef<Key>> constructed;
 1813|       |
 1814|  8.19k|    to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
 1815|       |
 1816|       |    // Parses a multi() or multi_a() from its string representation. Returns false on parsing error.
 1817|  8.19k|    const auto parse_multi_exp = [&](Span<const char>& in, const bool is_multi_a) -> bool {
 1818|  8.19k|        const auto max_keys{is_multi_a ? MAX_PUBKEYS_PER_MULTI_A : MAX_PUBKEYS_PER_MULTISIG};
 1819|  8.19k|        const auto required_ctx{is_multi_a ? MiniscriptContext::TAPSCRIPT : MiniscriptContext::P2WSH};
 1820|  8.19k|        if (ctx.MsContext() != required_ctx) return false;
 1821|       |        // Get threshold
 1822|  8.19k|        int next_comma = FindNextChar(in, ',');
 1823|  8.19k|        if (next_comma < 1) return false;
 1824|  8.19k|        const auto k_to_integral{ToIntegral<int64_t>(std::string_view(in.data(), next_comma))};
 1825|  8.19k|        if (!k_to_integral.has_value()) return false;
 1826|  8.19k|        const int64_t k{k_to_integral.value()};
 1827|  8.19k|        in = in.subspan(next_comma + 1);
 1828|       |        // Get keys. It is compatible for both compressed and x-only keys.
 1829|  8.19k|        std::vector<Key> keys;
 1830|  8.19k|        while (next_comma != -1) {
 1831|  8.19k|            next_comma = FindNextChar(in, ',');
 1832|  8.19k|            int key_length = (next_comma == -1) ? FindNextChar(in, ')') : next_comma;
 1833|  8.19k|            if (key_length < 1) return false;
 1834|  8.19k|            auto key = ctx.FromString(in.begin(), in.begin() + key_length);
 1835|  8.19k|            if (!key) return false;
 1836|  8.19k|            keys.push_back(std::move(*key));
 1837|  8.19k|            in = in.subspan(key_length + 1);
 1838|  8.19k|        }
 1839|  8.19k|        if (keys.size() < 1 || keys.size() > max_keys) return false;
 1840|  8.19k|        if (k < 1 || k > (int64_t)keys.size()) return false;
 1841|  8.19k|        if (is_multi_a) {
 1842|       |            // (push + xonly-key + CHECKSIG[ADD]) * n + k + OP_NUMEQUAL(VERIFY), minus one.
 1843|  8.19k|            script_size += (1 + 32 + 1) * keys.size() + BuildScript(k).size();
 1844|  8.19k|            constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::MULTI_A, std::move(keys), k));
 1845|  8.19k|        } else {
 1846|  8.19k|            script_size += 2 + (keys.size() > 16) + (k > 16) + 34 * keys.size();
 1847|  8.19k|            constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::MULTI, std::move(keys), k));
 1848|  8.19k|        }
 1849|  8.19k|        return true;
 1850|  8.19k|    };
 1851|       |
 1852|  27.4M|    while (!to_parse.empty()) {
  ------------------
  |  Branch (1852:12): [True: 27.3M, False: 6.10k]
  ------------------
 1853|  27.3M|        if (script_size > max_size) return {};
  ------------------
  |  Branch (1853:13): [True: 9, False: 27.3M]
  ------------------
 1854|       |
 1855|       |        // Get the current context we are decoding within
 1856|  27.3M|        auto [cur_context, n, k] = to_parse.back();
 1857|  27.3M|        to_parse.pop_back();
 1858|       |
 1859|  27.3M|        switch (cur_context) {
  ------------------
  |  Branch (1859:17): [True: 0, False: 27.3M]
  ------------------
 1860|   272k|        case ParseContext::WRAPPED_EXPR: {
  ------------------
  |  Branch (1860:9): [True: 272k, False: 27.1M]
  ------------------
 1861|   272k|            std::optional<size_t> colon_index{};
 1862|  27.7M|            for (size_t i = 1; i < in.size(); ++i) {
  ------------------
  |  Branch (1862:32): [True: 27.7M, False: 254]
  ------------------
 1863|  27.7M|                if (in[i] == ':') {
  ------------------
  |  Branch (1863:21): [True: 82.8k, False: 27.7M]
  ------------------
 1864|  82.8k|                    colon_index = i;
 1865|  82.8k|                    break;
 1866|  82.8k|                }
 1867|  27.7M|                if (in[i] < 'a' || in[i] > 'z') break;
  ------------------
  |  Branch (1867:21): [True: 189k, False: 27.5M]
  |  Branch (1867:36): [True: 1, False: 27.5M]
  ------------------
 1868|  27.7M|            }
 1869|       |            // If there is no colon, this loop won't execute
 1870|   272k|            bool last_was_v{false};
 1871|  27.1M|            for (size_t j = 0; colon_index && j < *colon_index; ++j) {
  ------------------
  |  Branch (1871:32): [True: 26.9M, False: 189k]
  |  Branch (1871:47): [True: 26.8M, False: 82.7k]
  ------------------
 1872|  26.8M|                if (script_size > max_size) return {};
  ------------------
  |  Branch (1872:21): [True: 5, False: 26.8M]
  ------------------
 1873|  26.8M|                if (in[j] == 'a') {
  ------------------
  |  Branch (1873:21): [True: 300k, False: 26.5M]
  ------------------
 1874|   300k|                    script_size += 2;
 1875|   300k|                    to_parse.emplace_back(ParseContext::ALT, -1, -1);
 1876|  26.5M|                } else if (in[j] == 's') {
  ------------------
  |  Branch (1876:28): [True: 151k, False: 26.4M]
  ------------------
 1877|   151k|                    script_size += 1;
 1878|   151k|                    to_parse.emplace_back(ParseContext::SWAP, -1, -1);
 1879|  26.4M|                } else if (in[j] == 'c') {
  ------------------
  |  Branch (1879:28): [True: 9.44M, False: 17.0M]
  ------------------
 1880|  9.44M|                    script_size += 1;
 1881|  9.44M|                    to_parse.emplace_back(ParseContext::CHECK, -1, -1);
 1882|  17.0M|                } else if (in[j] == 'd') {
  ------------------
  |  Branch (1882:28): [True: 186k, False: 16.8M]
  ------------------
 1883|   186k|                    script_size += 3;
 1884|   186k|                    to_parse.emplace_back(ParseContext::DUP_IF, -1, -1);
 1885|  16.8M|                } else if (in[j] == 'j') {
  ------------------
  |  Branch (1885:28): [True: 113k, False: 16.7M]
  ------------------
 1886|   113k|                    script_size += 4;
 1887|   113k|                    to_parse.emplace_back(ParseContext::NON_ZERO, -1, -1);
 1888|  16.7M|                } else if (in[j] == 'n') {
  ------------------
  |  Branch (1888:28): [True: 362k, False: 16.3M]
  ------------------
 1889|   362k|                    script_size += 1;
 1890|   362k|                    to_parse.emplace_back(ParseContext::ZERO_NOTEQUAL, -1, -1);
 1891|  16.3M|                } else if (in[j] == 'v') {
  ------------------
  |  Branch (1891:28): [True: 83.6k, False: 16.2M]
  ------------------
 1892|       |                    // do not permit "...vv...:"; it's not valid, and also doesn't trigger early
 1893|       |                    // failure as script_size isn't incremented.
 1894|  83.6k|                    if (last_was_v) return {};
  ------------------
  |  Branch (1894:25): [True: 1, False: 83.6k]
  ------------------
 1895|  83.6k|                    to_parse.emplace_back(ParseContext::VERIFY, -1, -1);
 1896|  16.2M|                } else if (in[j] == 'u') {
  ------------------
  |  Branch (1896:28): [True: 2.14M, False: 14.1M]
  ------------------
 1897|  2.14M|                    script_size += 4;
 1898|  2.14M|                    to_parse.emplace_back(ParseContext::WRAP_U, -1, -1);
 1899|  14.1M|                } else if (in[j] == 't') {
  ------------------
  |  Branch (1899:28): [True: 8.59M, False: 5.51M]
  ------------------
 1900|  8.59M|                    script_size += 1;
 1901|  8.59M|                    to_parse.emplace_back(ParseContext::WRAP_T, -1, -1);
 1902|  8.59M|                } else if (in[j] == 'l') {
  ------------------
  |  Branch (1902:28): [True: 5.51M, False: 51]
  ------------------
 1903|       |                    // The l: wrapper is equivalent to or_i(0,X)
 1904|  5.51M|                    script_size += 4;
 1905|  5.51M|                    constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::JUST_0));
 1906|  5.51M|                    to_parse.emplace_back(ParseContext::OR_I, -1, -1);
 1907|  5.51M|                } else {
 1908|     51|                    return {};
 1909|     51|                }
 1910|  26.8M|                last_was_v = (in[j] == 'v');
 1911|  26.8M|            }
 1912|   272k|            to_parse.emplace_back(ParseContext::EXPR, -1, -1);
 1913|   272k|            if (colon_index) in = in.subspan(*colon_index + 1);
  ------------------
  |  Branch (1913:17): [True: 82.7k, False: 189k]
  ------------------
 1914|   272k|            break;
 1915|   272k|        }
 1916|   272k|        case ParseContext::EXPR: {
  ------------------
  |  Branch (1916:9): [True: 272k, False: 27.1M]
  ------------------
 1917|   272k|            if (Const("0", in)) {
  ------------------
  |  Branch (1917:17): [True: 83.0k, False: 189k]
  ------------------
 1918|  83.0k|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::JUST_0));
 1919|   189k|            } else if (Const("1", in)) {
  ------------------
  |  Branch (1919:24): [True: 61.1k, False: 128k]
  ------------------
 1920|  61.1k|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::JUST_1));
 1921|   128k|            } else if (Const("pk(", in)) {
  ------------------
  |  Branch (1921:24): [True: 18.6k, False: 109k]
  ------------------
 1922|  18.6k|                auto res = ParseKeyEnd<Key, Ctx>(in, ctx);
 1923|  18.6k|                if (!res) return {};
  ------------------
  |  Branch (1923:21): [True: 72, False: 18.6k]
  ------------------
 1924|  18.6k|                auto& [key, key_size] = *res;
 1925|  18.6k|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_C, Vector(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_K, Vector(std::move(key))))));
 1926|  18.6k|                in = in.subspan(key_size + 1);
 1927|  18.6k|                script_size += IsTapscript(ctx.MsContext()) ? 33 : 34;
  ------------------
  |  Branch (1927:32): [True: 16.9k, False: 1.64k]
  ------------------
 1928|   109k|            } else if (Const("pkh(", in)) {
  ------------------
  |  Branch (1928:24): [True: 7.71k, False: 102k]
  ------------------
 1929|  7.71k|                auto res = ParseKeyEnd<Key>(in, ctx);
 1930|  7.71k|                if (!res) return {};
  ------------------
  |  Branch (1930:21): [True: 28, False: 7.68k]
  ------------------
 1931|  7.68k|                auto& [key, key_size] = *res;
 1932|  7.68k|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_C, Vector(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_H, Vector(std::move(key))))));
 1933|  7.68k|                in = in.subspan(key_size + 1);
 1934|  7.68k|                script_size += 24;
 1935|   102k|            } else if (Const("pk_k(", in)) {
  ------------------
  |  Branch (1935:24): [True: 277, False: 101k]
  ------------------
 1936|    277|                auto res = ParseKeyEnd<Key>(in, ctx);
 1937|    277|                if (!res) return {};
  ------------------
  |  Branch (1937:21): [True: 2, False: 275]
  ------------------
 1938|    275|                auto& [key, key_size] = *res;
 1939|    275|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_K, Vector(std::move(key))));
 1940|    275|                in = in.subspan(key_size + 1);
 1941|    275|                script_size += IsTapscript(ctx.MsContext()) ? 32 : 33;
  ------------------
  |  Branch (1941:32): [True: 197, False: 78]
  ------------------
 1942|   101k|            } else if (Const("pk_h(", in)) {
  ------------------
  |  Branch (1942:24): [True: 10.7k, False: 91.0k]
  ------------------
 1943|  10.7k|                auto res = ParseKeyEnd<Key>(in, ctx);
 1944|  10.7k|                if (!res) return {};
  ------------------
  |  Branch (1944:21): [True: 21, False: 10.7k]
  ------------------
 1945|  10.7k|                auto& [key, key_size] = *res;
 1946|  10.7k|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::PK_H, Vector(std::move(key))));
 1947|  10.7k|                in = in.subspan(key_size + 1);
 1948|  10.7k|                script_size += 23;
 1949|  91.0k|            } else if (Const("sha256(", in)) {
  ------------------
  |  Branch (1949:24): [True: 324, False: 90.7k]
  ------------------
 1950|    324|                auto res = ParseHexStrEnd(in, 32, ctx);
 1951|    324|                if (!res) return {};
  ------------------
  |  Branch (1951:21): [True: 63, False: 261]
  ------------------
 1952|    261|                auto& [hash, hash_size] = *res;
 1953|    261|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::SHA256, std::move(hash)));
 1954|    261|                in = in.subspan(hash_size + 1);
 1955|    261|                script_size += 38;
 1956|  90.7k|            } else if (Const("ripemd160(", in)) {
  ------------------
  |  Branch (1956:24): [True: 877, False: 89.8k]
  ------------------
 1957|    877|                auto res = ParseHexStrEnd(in, 20, ctx);
 1958|    877|                if (!res) return {};
  ------------------
  |  Branch (1958:21): [True: 21, False: 856]
  ------------------
 1959|    856|                auto& [hash, hash_size] = *res;
 1960|    856|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::RIPEMD160, std::move(hash)));
 1961|    856|                in = in.subspan(hash_size + 1);
 1962|    856|                script_size += 26;
 1963|  89.8k|            } else if (Const("hash256(", in)) {
  ------------------
  |  Branch (1963:24): [True: 216, False: 89.6k]
  ------------------
 1964|    216|                auto res = ParseHexStrEnd(in, 32, ctx);
 1965|    216|                if (!res) return {};
  ------------------
  |  Branch (1965:21): [True: 5, False: 211]
  ------------------
 1966|    211|                auto& [hash, hash_size] = *res;
 1967|    211|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::HASH256, std::move(hash)));
 1968|    211|                in = in.subspan(hash_size + 1);
 1969|    211|                script_size += 38;
 1970|  89.6k|            } else if (Const("hash160(", in)) {
  ------------------
  |  Branch (1970:24): [True: 707, False: 88.9k]
  ------------------
 1971|    707|                auto res = ParseHexStrEnd(in, 20, ctx);
 1972|    707|                if (!res) return {};
  ------------------
  |  Branch (1972:21): [True: 18, False: 689]
  ------------------
 1973|    689|                auto& [hash, hash_size] = *res;
 1974|    689|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::HASH160, std::move(hash)));
 1975|    689|                in = in.subspan(hash_size + 1);
 1976|    689|                script_size += 26;
 1977|  88.9k|            } else if (Const("after(", in)) {
  ------------------
  |  Branch (1977:24): [True: 4.99k, False: 83.9k]
  ------------------
 1978|  4.99k|                int arg_size = FindNextChar(in, ')');
 1979|  4.99k|                if (arg_size < 1) return {};
  ------------------
  |  Branch (1979:21): [True: 3, False: 4.99k]
  ------------------
 1980|  4.99k|                const auto num{ToIntegral<int64_t>(std::string_view(in.data(), arg_size))};
 1981|  4.99k|                if (!num.has_value() || *num < 1 || *num >= 0x80000000L) return {};
  ------------------
  |  Branch (1981:21): [True: 73, False: 4.91k]
  |  Branch (1981:41): [True: 124, False: 4.79k]
  |  Branch (1981:53): [True: 38, False: 4.75k]
  ------------------
 1982|  4.75k|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::AFTER, *num));
 1983|  4.75k|                in = in.subspan(arg_size + 1);
 1984|  4.75k|                script_size += 1 + (*num > 16) + (*num > 0x7f) + (*num > 0x7fff) + (*num > 0x7fffff);
 1985|  83.9k|            } else if (Const("older(", in)) {
  ------------------
  |  Branch (1985:24): [True: 10.0k, False: 73.9k]
  ------------------
 1986|  10.0k|                int arg_size = FindNextChar(in, ')');
 1987|  10.0k|                if (arg_size < 1) return {};
  ------------------
  |  Branch (1987:21): [True: 3, False: 10.0k]
  ------------------
 1988|  10.0k|                const auto num{ToIntegral<int64_t>(std::string_view(in.data(), arg_size))};
 1989|  10.0k|                if (!num.has_value() || *num < 1 || *num >= 0x80000000L) return {};
  ------------------
  |  Branch (1989:21): [True: 73, False: 9.94k]
  |  Branch (1989:41): [True: 88, False: 9.86k]
  |  Branch (1989:53): [True: 40, False: 9.82k]
  ------------------
 1990|  9.82k|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::OLDER, *num));
 1991|  9.82k|                in = in.subspan(arg_size + 1);
 1992|  9.82k|                script_size += 1 + (*num > 16) + (*num > 0x7f) + (*num > 0x7fff) + (*num > 0x7fffff);
 1993|  73.9k|            } else if (Const("multi(", in)) {
  ------------------
  |  Branch (1993:24): [True: 3.22k, False: 70.7k]
  ------------------
 1994|  3.22k|                if (!parse_multi_exp(in, /* is_multi_a = */false)) return {};
  ------------------
  |  Branch (1994:21): [True: 449, False: 2.77k]
  ------------------
 1995|  70.7k|            } else if (Const("multi_a(", in)) {
  ------------------
  |  Branch (1995:24): [True: 4.39k, False: 66.3k]
  ------------------
 1996|  4.39k|                if (!parse_multi_exp(in, /* is_multi_a = */true)) return {};
  ------------------
  |  Branch (1996:21): [True: 7, False: 4.39k]
  ------------------
 1997|  66.3k|            } else if (Const("thresh(", in)) {
  ------------------
  |  Branch (1997:24): [True: 7.75k, False: 58.5k]
  ------------------
 1998|  7.75k|                int next_comma = FindNextChar(in, ',');
 1999|  7.75k|                if (next_comma < 1) return {};
  ------------------
  |  Branch (1999:21): [True: 1, False: 7.75k]
  ------------------
 2000|  7.75k|                const auto k{ToIntegral<int64_t>(std::string_view(in.data(), next_comma))};
 2001|  7.75k|                if (!k.has_value() || *k < 1) return {};
  ------------------
  |  Branch (2001:21): [True: 10, False: 7.74k]
  |  Branch (2001:39): [True: 77, False: 7.67k]
  ------------------
 2002|  7.67k|                in = in.subspan(next_comma + 1);
 2003|       |                // n = 1 here because we read the first WRAPPED_EXPR before reaching THRESH
 2004|  7.67k|                to_parse.emplace_back(ParseContext::THRESH, 1, *k);
 2005|  7.67k|                to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
 2006|  7.67k|                script_size += 2 + (*k > 16) + (*k > 0x7f) + (*k > 0x7fff) + (*k > 0x7fffff);
 2007|  58.5k|            } else if (Const("andor(", in)) {
  ------------------
  |  Branch (2007:24): [True: 5.98k, False: 52.5k]
  ------------------
 2008|  5.98k|                to_parse.emplace_back(ParseContext::ANDOR, -1, -1);
 2009|  5.98k|                to_parse.emplace_back(ParseContext::CLOSE_BRACKET, -1, -1);
 2010|  5.98k|                to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
 2011|  5.98k|                to_parse.emplace_back(ParseContext::COMMA, -1, -1);
 2012|  5.98k|                to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
 2013|  5.98k|                to_parse.emplace_back(ParseContext::COMMA, -1, -1);
 2014|  5.98k|                to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
 2015|  5.98k|                script_size += 5;
 2016|  52.5k|            } else {
 2017|  52.5k|                if (Const("and_n(", in)) {
  ------------------
  |  Branch (2017:21): [True: 3.81k, False: 48.7k]
  ------------------
 2018|  3.81k|                    to_parse.emplace_back(ParseContext::AND_N, -1, -1);
 2019|  3.81k|                    script_size += 5;
 2020|  48.7k|                } else if (Const("and_b(", in)) {
  ------------------
  |  Branch (2020:28): [True: 13.5k, False: 35.1k]
  ------------------
 2021|  13.5k|                    to_parse.emplace_back(ParseContext::AND_B, -1, -1);
 2022|  13.5k|                    script_size += 2;
 2023|  35.1k|                } else if (Const("and_v(", in)) {
  ------------------
  |  Branch (2023:28): [True: 2.54k, False: 32.6k]
  ------------------
 2024|  2.54k|                    to_parse.emplace_back(ParseContext::AND_V, -1, -1);
 2025|  2.54k|                    script_size += 1;
 2026|  32.6k|                } else if (Const("or_b(", in)) {
  ------------------
  |  Branch (2026:28): [True: 4.92k, False: 27.7k]
  ------------------
 2027|  4.92k|                    to_parse.emplace_back(ParseContext::OR_B, -1, -1);
 2028|  4.92k|                    script_size += 2;
 2029|  27.7k|                } else if (Const("or_c(", in)) {
  ------------------
  |  Branch (2029:28): [True: 3.77k, False: 23.9k]
  ------------------
 2030|  3.77k|                    to_parse.emplace_back(ParseContext::OR_C, -1, -1);
 2031|  3.77k|                    script_size += 3;
 2032|  23.9k|                } else if (Const("or_d(", in)) {
  ------------------
  |  Branch (2032:28): [True: 6.09k, False: 17.8k]
  ------------------
 2033|  6.09k|                    to_parse.emplace_back(ParseContext::OR_D, -1, -1);
 2034|  6.09k|                    script_size += 4;
 2035|  17.8k|                } else if (Const("or_i(", in)) {
  ------------------
  |  Branch (2035:28): [True: 17.3k, False: 491]
  ------------------
 2036|  17.3k|                    to_parse.emplace_back(ParseContext::OR_I, -1, -1);
 2037|  17.3k|                    script_size += 4;
 2038|  17.3k|                } else {
 2039|    491|                    return {};
 2040|    491|                }
 2041|  52.0k|                to_parse.emplace_back(ParseContext::CLOSE_BRACKET, -1, -1);
 2042|  52.0k|                to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
 2043|  52.0k|                to_parse.emplace_back(ParseContext::COMMA, -1, -1);
 2044|  52.0k|                to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
 2045|  52.0k|            }
 2046|   271k|            break;
 2047|   272k|        }
 2048|   299k|        case ParseContext::ALT: {
  ------------------
  |  Branch (2048:9): [True: 299k, False: 27.0M]
  ------------------
 2049|   299k|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_A, Vector(std::move(constructed.back())));
 2050|   299k|            break;
 2051|   272k|        }
 2052|   149k|        case ParseContext::SWAP: {
  ------------------
  |  Branch (2052:9): [True: 149k, False: 27.2M]
  ------------------
 2053|   149k|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_S, Vector(std::move(constructed.back())));
 2054|   149k|            break;
 2055|   272k|        }
 2056|  9.14M|        case ParseContext::CHECK: {
  ------------------
  |  Branch (2056:9): [True: 9.14M, False: 18.2M]
  ------------------
 2057|  9.14M|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_C, Vector(std::move(constructed.back())));
 2058|  9.14M|            break;
 2059|   272k|        }
 2060|   185k|        case ParseContext::DUP_IF: {
  ------------------
  |  Branch (2060:9): [True: 185k, False: 27.2M]
  ------------------
 2061|   185k|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_D, Vector(std::move(constructed.back())));
 2062|   185k|            break;
 2063|   272k|        }
 2064|   112k|        case ParseContext::NON_ZERO: {
  ------------------
  |  Branch (2064:9): [True: 112k, False: 27.2M]
  ------------------
 2065|   112k|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_J, Vector(std::move(constructed.back())));
 2066|   112k|            break;
 2067|   272k|        }
 2068|   359k|        case ParseContext::ZERO_NOTEQUAL: {
  ------------------
  |  Branch (2068:9): [True: 359k, False: 27.0M]
  ------------------
 2069|   359k|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_N, Vector(std::move(constructed.back())));
 2070|   359k|            break;
 2071|   272k|        }
 2072|  83.0k|        case ParseContext::VERIFY: {
  ------------------
  |  Branch (2072:9): [True: 83.0k, False: 27.3M]
  ------------------
 2073|  83.0k|            script_size += (constructed.back()->GetType() << "x"_mst);
 2074|  83.0k|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::WRAP_V, Vector(std::move(constructed.back())));
 2075|  83.0k|            break;
 2076|   272k|        }
 2077|  2.14M|        case ParseContext::WRAP_U: {
  ------------------
  |  Branch (2077:9): [True: 2.14M, False: 25.2M]
  ------------------
 2078|  2.14M|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::OR_I, Vector(std::move(constructed.back()), MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::JUST_0)));
 2079|  2.14M|            break;
 2080|   272k|        }
 2081|  8.54M|        case ParseContext::WRAP_T: {
  ------------------
  |  Branch (2081:9): [True: 8.54M, False: 18.8M]
  ------------------
 2082|  8.54M|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::AND_V, Vector(std::move(constructed.back()), MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::JUST_1)));
 2083|  8.54M|            break;
 2084|   272k|        }
 2085|  13.4k|        case ParseContext::AND_B: {
  ------------------
  |  Branch (2085:9): [True: 13.4k, False: 27.3M]
  ------------------
 2086|  13.4k|            BuildBack(ctx.MsContext(), Fragment::AND_B, constructed);
 2087|  13.4k|            break;
 2088|   272k|        }
 2089|  3.52k|        case ParseContext::AND_N: {
  ------------------
  |  Branch (2089:9): [True: 3.52k, False: 27.3M]
  ------------------
 2090|  3.52k|            auto mid = std::move(constructed.back());
 2091|  3.52k|            constructed.pop_back();
 2092|  3.52k|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::ANDOR, Vector(std::move(constructed.back()), std::move(mid), MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::JUST_0)));
 2093|  3.52k|            break;
 2094|   272k|        }
 2095|  2.28k|        case ParseContext::AND_V: {
  ------------------
  |  Branch (2095:9): [True: 2.28k, False: 27.3M]
  ------------------
 2096|  2.28k|            BuildBack(ctx.MsContext(), Fragment::AND_V, constructed);
 2097|  2.28k|            break;
 2098|   272k|        }
 2099|  4.79k|        case ParseContext::OR_B: {
  ------------------
  |  Branch (2099:9): [True: 4.79k, False: 27.3M]
  ------------------
 2100|  4.79k|            BuildBack(ctx.MsContext(), Fragment::OR_B, constructed);
 2101|  4.79k|            break;
 2102|   272k|        }
 2103|  3.65k|        case ParseContext::OR_C: {
  ------------------
  |  Branch (2103:9): [True: 3.65k, False: 27.3M]
  ------------------
 2104|  3.65k|            BuildBack(ctx.MsContext(), Fragment::OR_C, constructed);
 2105|  3.65k|            break;
 2106|   272k|        }
 2107|  5.69k|        case ParseContext::OR_D: {
  ------------------
  |  Branch (2107:9): [True: 5.69k, False: 27.3M]
  ------------------
 2108|  5.69k|            BuildBack(ctx.MsContext(), Fragment::OR_D, constructed);
 2109|  5.69k|            break;
 2110|   272k|        }
 2111|  5.52M|        case ParseContext::OR_I: {
  ------------------
  |  Branch (2111:9): [True: 5.52M, False: 21.8M]
  ------------------
 2112|  5.52M|            BuildBack(ctx.MsContext(), Fragment::OR_I, constructed);
 2113|  5.52M|            break;
 2114|   272k|        }
 2115|  5.47k|        case ParseContext::ANDOR: {
  ------------------
  |  Branch (2115:9): [True: 5.47k, False: 27.3M]
  ------------------
 2116|  5.47k|            auto right = std::move(constructed.back());
 2117|  5.47k|            constructed.pop_back();
 2118|  5.47k|            auto mid = std::move(constructed.back());
 2119|  5.47k|            constructed.pop_back();
 2120|  5.47k|            constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::ANDOR, Vector(std::move(constructed.back()), std::move(mid), std::move(right)));
 2121|  5.47k|            break;
 2122|   272k|        }
 2123|   143k|        case ParseContext::THRESH: {
  ------------------
  |  Branch (2123:9): [True: 143k, False: 27.2M]
  ------------------
 2124|   143k|            if (in.size() < 1) return {};
  ------------------
  |  Branch (2124:17): [True: 48, False: 143k]
  ------------------
 2125|   143k|            if (in[0] == ',') {
  ------------------
  |  Branch (2125:17): [True: 136k, False: 6.63k]
  ------------------
 2126|   136k|                in = in.subspan(1);
 2127|   136k|                to_parse.emplace_back(ParseContext::THRESH, n+1, k);
 2128|   136k|                to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
 2129|   136k|                script_size += 2;
 2130|   136k|            } else if (in[0] == ')') {
  ------------------
  |  Branch (2130:24): [True: 6.61k, False: 22]
  ------------------
 2131|  6.61k|                if (k > n) return {};
  ------------------
  |  Branch (2131:21): [True: 111, False: 6.50k]
  ------------------
 2132|  6.50k|                in = in.subspan(1);
 2133|       |                // Children are constructed in reverse order, so iterate from end to beginning
 2134|  6.50k|                std::vector<NodeRef<Key>> subs;
 2135|   146k|                for (int i = 0; i < n; ++i) {
  ------------------
  |  Branch (2135:33): [True: 139k, False: 6.50k]
  ------------------
 2136|   139k|                    subs.push_back(std::move(constructed.back()));
 2137|   139k|                    constructed.pop_back();
 2138|   139k|                }
 2139|  6.50k|                std::reverse(subs.begin(), subs.end());
 2140|  6.50k|                constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::THRESH, std::move(subs), k));
 2141|  6.50k|            } else {
 2142|     22|                return {};
 2143|     22|            }
 2144|   143k|            break;
 2145|   143k|        }
 2146|   143k|        case ParseContext::COMMA: {
  ------------------
  |  Branch (2146:9): [True: 62.2k, False: 27.3M]
  ------------------
 2147|  62.2k|            if (in.size() < 1 || in[0] != ',') return {};
  ------------------
  |  Branch (2147:17): [True: 23, False: 62.2k]
  |  Branch (2147:34): [True: 71, False: 62.1k]
  ------------------
 2148|  62.1k|            in = in.subspan(1);
 2149|  62.1k|            break;
 2150|  62.2k|        }
 2151|  55.8k|        case ParseContext::CLOSE_BRACKET: {
  ------------------
  |  Branch (2151:9): [True: 55.8k, False: 27.3M]
  ------------------
 2152|  55.8k|            if (in.size() < 1 || in[0] != ')') return {};
  ------------------
  |  Branch (2152:17): [True: 21, False: 55.8k]
  |  Branch (2152:34): [True: 20, False: 55.8k]
  ------------------
 2153|  55.8k|            in = in.subspan(1);
 2154|  55.8k|            break;
 2155|  55.8k|        }
 2156|  27.3M|        }
 2157|  27.3M|    }
 2158|       |
 2159|       |    // Sanity checks on the produced miniscript
 2160|  6.10k|    assert(constructed.size() == 1);
 2161|  6.10k|    assert(constructed[0]->ScriptSize() == script_size);
 2162|  6.10k|    if (in.size() > 0) return {};
  ------------------
  |  Branch (2162:9): [True: 674, False: 5.43k]
  ------------------
 2163|  5.43k|    NodeRef<Key> tl_node = std::move(constructed.front());
 2164|  5.43k|    tl_node->DuplicateKeyCheck(ctx);
 2165|  5.43k|    return tl_node;
 2166|  6.10k|}
miniscript.cpp:_ZN10miniscript8internal11ParseKeyEndI7CPubKeyN12_GLOBAL__N_113ParserContextEEENSt3__18optionalINS5_4pairIT_iEEEE4SpanIKcERKT0_:
 1752|  37.4k|{
 1753|  37.4k|    int key_size = FindNextChar(in, ')');
 1754|  37.4k|    if (key_size < 1) return {};
  ------------------
  |  Branch (1754:9): [True: 23, False: 37.4k]
  ------------------
 1755|  37.4k|    auto key = ctx.FromString(in.begin(), in.begin() + key_size);
 1756|  37.4k|    if (!key) return {};
  ------------------
  |  Branch (1756:9): [True: 100, False: 37.3k]
  ------------------
 1757|  37.3k|    return {{std::move(*key), key_size}};
 1758|  37.4k|}
miniscript.cpp:_ZN10miniscript8internal14ParseHexStrEndIN12_GLOBAL__N_113ParserContextEEENSt3__18optionalINS4_4pairINS4_6vectorIhNS4_9allocatorIhEEEEiEEEE4SpanIKcEmRKT_:
 1764|  2.12k|{
 1765|  2.12k|    int hash_size = FindNextChar(in, ')');
 1766|  2.12k|    if (hash_size < 1) return {};
  ------------------
  |  Branch (1766:9): [True: 6, False: 2.11k]
  ------------------
 1767|  2.11k|    std::string val = std::string(in.begin(), in.begin() + hash_size);
 1768|  2.11k|    if (!IsHex(val)) return {};
  ------------------
  |  Branch (1768:9): [True: 64, False: 2.05k]
  ------------------
 1769|  2.05k|    auto hash = ParseHex(val);
 1770|  2.05k|    if (hash.size() != expected_size) return {};
  ------------------
  |  Branch (1770:9): [True: 37, False: 2.01k]
  ------------------
 1771|  2.01k|    return {{std::move(hash), hash_size}};
 1772|  2.05k|}
_ZN10miniscript11MakeNodeRefI7CPubKeyJNS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentENSt3__16vectorIhNS6_9allocatorIhEEEEEEENS6_10unique_ptrIKNS_4NodeIT_EENS6_14default_deleteISF_EEEEDpOT0_:
  196|  2.01k|NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
_ZN10miniscript11MakeNodeRefI7CPubKeyJNS_8internal10NoDupCheckENS_17MiniscriptContextENS_8FragmentERKlEEENSt3__110unique_ptrIKNS_4NodeIT_EENS8_14default_deleteISD_EEEEDpOT0_:
  196|  14.5k|NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
miniscript.cpp:_ZZN10miniscript8internal5ParseI7CPubKeyN12_GLOBAL__N_113ParserContextEEENSt3__110unique_ptrIKNS_4NodeIT_EENS5_14default_deleteISA_EEEE4SpanIKcERKT0_ENKUlRSG_bE_clESK_b:
 1817|  7.62k|    const auto parse_multi_exp = [&](Span<const char>& in, const bool is_multi_a) -> bool {
 1818|  7.62k|        const auto max_keys{is_multi_a ? MAX_PUBKEYS_PER_MULTI_A : MAX_PUBKEYS_PER_MULTISIG};
  ------------------
  |  Branch (1818:29): [True: 4.39k, False: 3.22k]
  ------------------
 1819|  7.62k|        const auto required_ctx{is_multi_a ? MiniscriptContext::TAPSCRIPT : MiniscriptContext::P2WSH};
  ------------------
  |  Branch (1819:33): [True: 4.39k, False: 3.22k]
  ------------------
 1820|  7.62k|        if (ctx.MsContext() != required_ctx) return false;
  ------------------
  |  Branch (1820:13): [True: 4, False: 7.61k]
  ------------------
 1821|       |        // Get threshold
 1822|  7.61k|        int next_comma = FindNextChar(in, ',');
 1823|  7.61k|        if (next_comma < 1) return false;
  ------------------
  |  Branch (1823:13): [True: 3, False: 7.61k]
  ------------------
 1824|  7.61k|        const auto k_to_integral{ToIntegral<int64_t>(std::string_view(in.data(), next_comma))};
 1825|  7.61k|        if (!k_to_integral.has_value()) return false;
  ------------------
  |  Branch (1825:13): [True: 90, False: 7.52k]
  ------------------
 1826|  7.52k|        const int64_t k{k_to_integral.value()};
 1827|  7.52k|        in = in.subspan(next_comma + 1);
 1828|       |        // Get keys. It is compatible for both compressed and x-only keys.
 1829|  7.52k|        std::vector<Key> keys;
 1830|   467k|        while (next_comma != -1) {
  ------------------
  |  Branch (1830:16): [True: 459k, False: 7.35k]
  ------------------
 1831|   459k|            next_comma = FindNextChar(in, ',');
 1832|   459k|            int key_length = (next_comma == -1) ? FindNextChar(in, ')') : next_comma;
  ------------------
  |  Branch (1832:30): [True: 7.49k, False: 452k]
  ------------------
 1833|   459k|            if (key_length < 1) return false;
  ------------------
  |  Branch (1833:17): [True: 127, False: 459k]
  ------------------
 1834|   459k|            auto key = ctx.FromString(in.begin(), in.begin() + key_length);
 1835|   459k|            if (!key) return false;
  ------------------
  |  Branch (1835:17): [True: 39, False: 459k]
  ------------------
 1836|   459k|            keys.push_back(std::move(*key));
 1837|   459k|            in = in.subspan(key_length + 1);
 1838|   459k|        }
 1839|  7.35k|        if (keys.size() < 1 || keys.size() > max_keys) return false;
  ------------------
  |  Branch (1839:13): [True: 0, False: 7.35k]
  |  Branch (1839:32): [True: 20, False: 7.33k]
  ------------------
 1840|  7.33k|        if (k < 1 || k > (int64_t)keys.size()) return false;
  ------------------
  |  Branch (1840:13): [True: 76, False: 7.26k]
  |  Branch (1840:22): [True: 97, False: 7.16k]
  ------------------
 1841|  7.16k|        if (is_multi_a) {
  ------------------
  |  Branch (1841:13): [True: 4.39k, False: 2.77k]
  ------------------
 1842|       |            // (push + xonly-key + CHECKSIG[ADD]) * n + k + OP_NUMEQUAL(VERIFY), minus one.
 1843|  4.39k|            script_size += (1 + 32 + 1) * keys.size() + BuildScript(k).size();
 1844|  4.39k|            constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::MULTI_A, std::move(keys), k));
 1845|  4.39k|        } else {
 1846|  2.77k|            script_size += 2 + (keys.size() > 16) + (k > 16) + 34 * keys.size();
 1847|  2.77k|            constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::MULTI, std::move(keys), k));
 1848|  2.77k|        }
 1849|  7.16k|        return true;
 1850|  7.33k|    };
_ZNK10miniscript4NodeI7CPubKeyEeqERKS2_:
 1656|  2.71k|    bool operator==(const Node<Key>& arg) const { return Compare(*this, arg) == 0; }
_ZN10miniscript7CompareERKNS_4NodeI7CPubKeyEES4_:
  712|  2.71k|    {
  713|  2.71k|        std::vector<std::pair<const Node<Key>&, const Node<Key>&>> queue;
  714|  2.71k|        queue.emplace_back(node1, node2);
  715|  13.8M|        while (!queue.empty()) {
  ------------------
  |  Branch (715:16): [True: 13.8M, False: 2.71k]
  ------------------
  716|  13.8M|            const auto& [a, b] = queue.back();
  717|  13.8M|            queue.pop_back();
  718|  13.8M|            if (std::tie(a.fragment, a.k, a.keys, a.data) < std::tie(b.fragment, b.k, b.keys, b.data)) return -1;
  ------------------
  |  Branch (718:17): [True: 0, False: 13.8M]
  ------------------
  719|  13.8M|            if (std::tie(b.fragment, b.k, b.keys, b.data) < std::tie(a.fragment, a.k, a.keys, a.data)) return 1;
  ------------------
  |  Branch (719:17): [True: 0, False: 13.8M]
  ------------------
  720|  13.8M|            if (a.subs.size() < b.subs.size()) return -1;
  ------------------
  |  Branch (720:17): [True: 0, False: 13.8M]
  ------------------
  721|  13.8M|            if (b.subs.size() < a.subs.size()) return 1;
  ------------------
  |  Branch (721:17): [True: 0, False: 13.8M]
  ------------------
  722|  13.8M|            size_t n = a.subs.size();
  723|  27.6M|            for (size_t i = 0; i < n; ++i) {
  ------------------
  |  Branch (723:32): [True: 13.8M, False: 13.8M]
  ------------------
  724|  13.8M|                queue.emplace_back(*a.subs[n - 1 - i], *b.subs[n - 1 - i]);
  725|  13.8M|            }
  726|  13.8M|        }
  727|  2.71k|        return 0;
  728|  2.71k|    }
_ZNK10miniscript4Type2IfEb:
  153|  76.6M|    constexpr Type If(bool x) const { return Type(x ? m_flags : 0); }
  ------------------
  |  Branch (153:51): [True: 25.2M, False: 51.3M]
  ------------------

_ZN6script5ConstERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEER4SpanIKcE:
   16|  1.94M|{
   17|  1.94M|    if ((size_t)sp.size() >= str.size() && std::equal(str.begin(), str.end(), sp.begin())) {
  ------------------
  |  Branch (17:9): [True: 1.93M, False: 8.75k]
  |  Branch (17:44): [True: 272k, False: 1.66M]
  ------------------
   18|   272k|        sp = sp.subspan(str.size());
   19|   272k|        return true;
   20|   272k|    }
   21|  1.67M|    return false;
   22|  1.94M|}

_ZN10CScriptNum9serializeERKl:
  350|  9.64k|    {
  351|  9.64k|        if(value == 0)
  ------------------
  |  Branch (351:12): [True: 0, False: 9.64k]
  ------------------
  352|      0|            return std::vector<unsigned char>();
  353|       |
  354|  9.64k|        std::vector<unsigned char> result;
  355|  9.64k|        const bool neg = value < 0;
  356|  9.64k|        uint64_t absvalue = neg ? ~static_cast<uint64_t>(value) + 1 : static_cast<uint64_t>(value);
  ------------------
  |  Branch (356:29): [True: 0, False: 9.64k]
  ------------------
  357|       |
  358|  39.3k|        while(absvalue)
  ------------------
  |  Branch (358:15): [True: 29.7k, False: 9.64k]
  ------------------
  359|  29.7k|        {
  360|  29.7k|            result.push_back(absvalue & 0xff);
  361|  29.7k|            absvalue >>= 8;
  362|  29.7k|        }
  363|       |
  364|       |//    - If the most significant byte is >= 0x80 and the value is positive, push a
  365|       |//    new zero-byte to make the significant byte < 0x80 again.
  366|       |
  367|       |//    - If the most significant byte is >= 0x80 and the value is negative, push a
  368|       |//    new 0x80 byte that will be popped off when converting to an integral.
  369|       |
  370|       |//    - If the most significant byte is < 0x80 and the value is negative, add
  371|       |//    0x80 to it, since it will be subtracted and interpreted as a negative when
  372|       |//    converting to an integral.
  373|       |
  374|  9.64k|        if (result.back() & 0x80)
  ------------------
  |  Branch (374:13): [True: 1.13k, False: 8.50k]
  ------------------
  375|  1.13k|            result.push_back(neg ? 0x80 : 0);
  ------------------
  |  Branch (375:30): [True: 0, False: 1.13k]
  ------------------
  376|  8.50k|        else if (neg)
  ------------------
  |  Branch (376:18): [True: 0, False: 8.50k]
  ------------------
  377|      0|            result.back() |= 0x80;
  378|       |
  379|  9.64k|        return result;
  380|  9.64k|    }
_ZN7CScript14AppendDataSizeEj:
  418|  9.64k|    {
  419|  9.64k|        if (size < OP_PUSHDATA1) {
  ------------------
  |  Branch (419:13): [True: 9.64k, False: 0]
  ------------------
  420|  9.64k|            insert(end(), static_cast<value_type>(size));
  421|  9.64k|        } else if (size <= 0xff) {
  ------------------
  |  Branch (421:20): [True: 0, False: 0]
  ------------------
  422|      0|            insert(end(), OP_PUSHDATA1);
  423|      0|            insert(end(), static_cast<value_type>(size));
  424|      0|        } else if (size <= 0xffff) {
  ------------------
  |  Branch (424:20): [True: 0, False: 0]
  ------------------
  425|      0|            insert(end(), OP_PUSHDATA2);
  426|      0|            value_type data[2];
  427|      0|            WriteLE16(data, size);
  428|      0|            insert(end(), std::cbegin(data), std::cend(data));
  429|      0|        } else {
  430|      0|            insert(end(), OP_PUSHDATA4);
  431|      0|            value_type data[4];
  432|      0|            WriteLE32(data, size);
  433|      0|            insert(end(), std::cbegin(data), std::cend(data));
  434|      0|        }
  435|  9.64k|    }
_ZN7CScript10AppendDataENSt3__14spanIKhLm18446744073709551615EEE:
  438|  9.64k|    {
  439|  9.64k|        insert(end(), data.begin(), data.end());
  440|  9.64k|    }
_ZN7CScript10push_int64El:
  444|  35.4k|    {
  445|  35.4k|        if (n == -1 || (n >= 1 && n <= 16))
  ------------------
  |  Branch (445:13): [True: 0, False: 35.4k]
  |  Branch (445:25): [True: 35.4k, False: 0]
  |  Branch (445:35): [True: 25.7k, False: 9.64k]
  ------------------
  446|  25.7k|        {
  447|  25.7k|            push_back(n + (OP_1 - 1));
  448|  25.7k|        }
  449|  9.64k|        else if (n == 0)
  ------------------
  |  Branch (449:18): [True: 0, False: 9.64k]
  ------------------
  450|      0|        {
  451|      0|            push_back(OP_0);
  452|      0|        }
  453|  9.64k|        else
  454|  9.64k|        {
  455|  9.64k|            *this << CScriptNum::serialize(n);
  456|  9.64k|        }
  457|  35.4k|        return *this;
  458|  35.4k|    }
_ZN7CScriptlsEl:
  477|  35.4k|    CScript& operator<<(int64_t b) LIFETIMEBOUND { return push_int64(b); }
_ZN7CScriptlsENSt3__14spanIKSt4byteLm18446744073709551615EEE:
  494|  9.64k|    {
  495|  9.64k|        AppendDataSize(b.size());
  496|  9.64k|        AppendData({reinterpret_cast<const value_type*>(b.data()), b.size()});
  497|  9.64k|        return *this;
  498|  9.64k|    }
_ZN7CScriptlsENSt3__14spanIKhLm18446744073709551615EEE:
  502|  9.64k|    {
  503|  9.64k|        return *this << std::as_bytes(b);
  504|  9.64k|    }
_ZN7CScriptC2Ev:
  461|  35.4k|    CScript() = default;
_Z11BuildScriptIJRKlEE7CScriptDpOT_:
  617|  4.39k|{
  618|  4.39k|    CScript ret;
  619|  4.39k|    int cnt{0};
  620|       |
  621|  4.39k|    ([&ret, &cnt] (Ts&& input) {
  622|  4.39k|        if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<Ts>>, CScript>) {
  623|       |            // If it is a CScript, extend ret with it. Move or copy the first element instead.
  624|  4.39k|            if (cnt == 0) {
  625|  4.39k|                ret = std::forward<Ts>(input);
  626|  4.39k|            } else {
  627|  4.39k|                ret.insert(ret.end(), input.begin(), input.end());
  628|  4.39k|            }
  629|  4.39k|        } else {
  630|       |            // Otherwise invoke CScript::operator<<.
  631|  4.39k|            ret << input;
  632|  4.39k|        }
  633|  4.39k|        cnt++;
  634|  4.39k|    } (std::forward<Ts>(inputs)), ...);
  635|       |
  636|  4.39k|    return ret;
  637|  4.39k|}
_ZZ11BuildScriptIJRKlEE7CScriptDpOT_ENKUlS1_E_clES1_:
  621|  4.39k|    ([&ret, &cnt] (Ts&& input) {
  622|       |        if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<Ts>>, CScript>) {
  623|       |            // If it is a CScript, extend ret with it. Move or copy the first element instead.
  624|       |            if (cnt == 0) {
  625|       |                ret = std::forward<Ts>(input);
  626|       |            } else {
  627|       |                ret.insert(ret.end(), input.begin(), input.end());
  628|       |            }
  629|  4.39k|        } else {
  630|       |            // Otherwise invoke CScript::operator<<.
  631|  4.39k|            ret << input;
  632|  4.39k|        }
  633|  4.39k|        cnt++;
  634|  4.39k|    } (std::forward<Ts>(inputs)), ...);
_Z11BuildScriptIJRjEE7CScriptDpOT_:
  617|  28.2k|{
  618|  28.2k|    CScript ret;
  619|  28.2k|    int cnt{0};
  620|       |
  621|  28.2k|    ([&ret, &cnt] (Ts&& input) {
  622|  28.2k|        if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<Ts>>, CScript>) {
  623|       |            // If it is a CScript, extend ret with it. Move or copy the first element instead.
  624|  28.2k|            if (cnt == 0) {
  625|  28.2k|                ret = std::forward<Ts>(input);
  626|  28.2k|            } else {
  627|  28.2k|                ret.insert(ret.end(), input.begin(), input.end());
  628|  28.2k|            }
  629|  28.2k|        } else {
  630|       |            // Otherwise invoke CScript::operator<<.
  631|  28.2k|            ret << input;
  632|  28.2k|        }
  633|  28.2k|        cnt++;
  634|  28.2k|    } (std::forward<Ts>(inputs)), ...);
  635|       |
  636|  28.2k|    return ret;
  637|  28.2k|}
_ZZ11BuildScriptIJRjEE7CScriptDpOT_ENKUlS0_E_clES0_:
  621|  28.2k|    ([&ret, &cnt] (Ts&& input) {
  622|       |        if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<Ts>>, CScript>) {
  623|       |            // If it is a CScript, extend ret with it. Move or copy the first element instead.
  624|       |            if (cnt == 0) {
  625|       |                ret = std::forward<Ts>(input);
  626|       |            } else {
  627|       |                ret.insert(ret.end(), input.begin(), input.end());
  628|       |            }
  629|  28.2k|        } else {
  630|       |            // Otherwise invoke CScript::operator<<.
  631|  28.2k|            ret << input;
  632|  28.2k|        }
  633|  28.2k|        cnt++;
  634|  28.2k|    } (std::forward<Ts>(inputs)), ...);
_Z11BuildScriptIJRmEE7CScriptDpOT_:
  617|  2.77k|{
  618|  2.77k|    CScript ret;
  619|  2.77k|    int cnt{0};
  620|       |
  621|  2.77k|    ([&ret, &cnt] (Ts&& input) {
  622|  2.77k|        if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<Ts>>, CScript>) {
  623|       |            // If it is a CScript, extend ret with it. Move or copy the first element instead.
  624|  2.77k|            if (cnt == 0) {
  625|  2.77k|                ret = std::forward<Ts>(input);
  626|  2.77k|            } else {
  627|  2.77k|                ret.insert(ret.end(), input.begin(), input.end());
  628|  2.77k|            }
  629|  2.77k|        } else {
  630|       |            // Otherwise invoke CScript::operator<<.
  631|  2.77k|            ret << input;
  632|  2.77k|        }
  633|  2.77k|        cnt++;
  634|  2.77k|    } (std::forward<Ts>(inputs)), ...);
  635|       |
  636|  2.77k|    return ret;
  637|  2.77k|}
_ZZ11BuildScriptIJRmEE7CScriptDpOT_ENKUlS0_E_clES0_:
  621|  2.77k|    ([&ret, &cnt] (Ts&& input) {
  622|       |        if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<Ts>>, CScript>) {
  623|       |            // If it is a CScript, extend ret with it. Move or copy the first element instead.
  624|       |            if (cnt == 0) {
  625|       |                ret = std::forward<Ts>(input);
  626|       |            } else {
  627|       |                ret.insert(ret.end(), input.begin(), input.end());
  628|       |            }
  629|  2.77k|        } else {
  630|       |            // Otherwise invoke CScript::operator<<.
  631|  2.77k|            ret << input;
  632|  2.77k|        }
  633|  2.77k|        cnt++;
  634|  2.77k|    } (std::forward<Ts>(inputs)), ...);

secp256k1.c:secp256k1_ecmult_gen_context_clear:
   26|      2|static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) {
   27|      2|    ctx->built = 0;
   28|      2|    secp256k1_scalar_clear(&ctx->scalar_offset);
   29|      2|    secp256k1_ge_clear(&ctx->ge_offset);
   30|      2|    secp256k1_fe_clear(&ctx->proj_blind);
   31|      2|}
secp256k1.c:secp256k1_ecmult_gen_context_is_built:
   22|      4|static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) {
   23|      4|    return ctx->built;
   24|      4|}

secp256k1.c:secp256k1_fe_clear:
   21|      2|SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) {
   22|      2|    secp256k1_memclear(a, sizeof(secp256k1_fe));
   23|      2|}

secp256k1.c:secp256k1_ge_clear:
  305|      2|static void secp256k1_ge_clear(secp256k1_ge *r) {
  306|      2|    secp256k1_memclear(r, sizeof(secp256k1_ge));
  307|      2|}

secp256k1.c:secp256k1_scalar_clear:
   30|      2|SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) {
   31|      2|    secp256k1_memclear(r, sizeof(secp256k1_scalar));
   32|      2|}

secp256k1_context_preallocated_destroy:
  176|      2|void secp256k1_context_preallocated_destroy(secp256k1_context* ctx) {
  177|      2|    ARG_CHECK_VOID(ctx == NULL || secp256k1_context_is_proper(ctx));
  ------------------
  |  |   52|      2|#define ARG_CHECK_VOID(cond) do { \
  |  |   53|      2|    if (EXPECT(!(cond), 0)) { \
  |  |  ------------------
  |  |  |  |  136|      4|#define EXPECT(x,c) __builtin_expect((x),(c))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:21): [True: 0, False: 2]
  |  |  |  |  |  Branch (136:39): [True: 0, False: 2]
  |  |  |  |  |  Branch (136:39): [True: 2, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   54|      0|        secp256k1_callback_call(&ctx->illegal_callback, #cond); \
  |  |   55|      0|        return; \
  |  |   56|      0|    } \
  |  |   57|      2|} while(0)
  |  |  ------------------
  |  |  |  Branch (57:9): [Folded - Ignored]
  |  |  ------------------
  ------------------
  178|       |
  179|       |    /* Defined as noop */
  180|      2|    if (ctx == NULL) {
  ------------------
  |  Branch (180:9): [True: 0, False: 2]
  ------------------
  181|      0|        return;
  182|      0|    }
  183|       |
  184|      2|    secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx);
  185|      2|}
secp256k1_context_destroy:
  187|      2|void secp256k1_context_destroy(secp256k1_context* ctx) {
  188|      2|    ARG_CHECK_VOID(ctx == NULL || secp256k1_context_is_proper(ctx));
  ------------------
  |  |   52|      2|#define ARG_CHECK_VOID(cond) do { \
  |  |   53|      2|    if (EXPECT(!(cond), 0)) { \
  |  |  ------------------
  |  |  |  |  136|      4|#define EXPECT(x,c) __builtin_expect((x),(c))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:21): [True: 0, False: 2]
  |  |  |  |  |  Branch (136:39): [True: 0, False: 2]
  |  |  |  |  |  Branch (136:39): [True: 2, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   54|      0|        secp256k1_callback_call(&ctx->illegal_callback, #cond); \
  |  |   55|      0|        return; \
  |  |   56|      0|    } \
  |  |   57|      2|} while(0)
  |  |  ------------------
  |  |  |  Branch (57:9): [Folded - Ignored]
  |  |  ------------------
  ------------------
  189|       |
  190|       |    /* Defined as noop */
  191|      2|    if (ctx == NULL) {
  ------------------
  |  Branch (191:9): [True: 0, False: 2]
  ------------------
  192|      0|        return;
  193|      0|    }
  194|       |
  195|      2|    secp256k1_context_preallocated_destroy(ctx);
  196|      2|    free(ctx);
  197|      2|}
secp256k1.c:secp256k1_context_is_proper:
   82|      4|static int secp256k1_context_is_proper(const secp256k1_context* ctx) {
   83|      4|    return secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx);
   84|      4|}

secp256k1.c:secp256k1_memclear:
  223|      6|static SECP256K1_INLINE void secp256k1_memclear(void *ptr, size_t len) {
  224|       |#if defined(_MSC_VER)
  225|       |    /* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */
  226|       |    SecureZeroMemory(ptr, len);
  227|       |#elif defined(__GNUC__)
  228|       |    /* We use a memory barrier that scares the compiler away from optimizing out the memset.
  229|       |     *
  230|       |     * Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
  231|       |     * in BoringSSL (ISC License):
  232|       |     *    As best as we can tell, this is sufficient to break any optimisations that
  233|       |     *    might try to eliminate "superfluous" memsets.
  234|       |     * This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it
  235|       |     * is pretty efficient, because the compiler can still implement the memset() efficently,
  236|       |     * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
  237|       |     * Yang et al. (USENIX Security 2017) for more background.
  238|       |     */
  239|      6|    memset(ptr, 0, len);
  240|      6|    __asm__ __volatile__("" : : "r"(ptr) : "memory");
  241|       |#else
  242|       |    void *(*volatile const volatile_memset)(void *, int, size_t) = memset;
  243|       |    volatile_memset(ptr, 0, len);
  244|       |#endif
  245|       |#ifdef VERIFY
  246|       |    SECP256K1_CHECKMEM_UNDEFINE(ptr, len);
  247|       |#endif
  248|      6|}

_Z20GetSizeOfCompactSizem:
  298|  4.13k|{
  299|  4.13k|    if (nSize < 253)             return sizeof(unsigned char);
  ------------------
  |  Branch (299:9): [True: 0, False: 4.13k]
  ------------------
  300|  4.13k|    else if (nSize <= std::numeric_limits<uint16_t>::max()) return sizeof(unsigned char) + sizeof(uint16_t);
  ------------------
  |  Branch (300:14): [True: 0, False: 4.13k]
  ------------------
  301|  4.13k|    else if (nSize <= std::numeric_limits<unsigned int>::max())  return sizeof(unsigned char) + sizeof(unsigned int);
  ------------------
  |  Branch (301:14): [True: 4.13k, False: 0]
  ------------------
  302|      0|    else                         return sizeof(unsigned char) + sizeof(uint64_t);
  303|  4.13k|}

_ZNK4SpanIKcE4dataEv:
  174|  30.3k|    constexpr C* data() const noexcept { return m_data; }
_ZNK4SpanIKcE4sizeEv:
  187|  55.9M|    constexpr std::size_t size() const noexcept { return m_size; }
_ZNK4SpanIKcE5beginEv:
  175|  2.93M|    constexpr C* begin() const noexcept { return m_data; }
_ZNK4SpanIKhE4sizeEv:
  187|  65.5k|    constexpr std::size_t size() const noexcept { return m_size; }
_ZNK4SpanIKhE5beginEv:
  175|  65.5k|    constexpr C* begin() const noexcept { return m_data; }
_ZNK4SpanIKhE3endEv:
  176|  65.5k|    constexpr C* end() const noexcept { return m_data + m_size; }
_ZN4SpanIKhEC2INSt3__16vectorIhNS3_9allocatorIhEEEEEERKT_NS3_9enable_ifIXaaaantsr7is_SpanIS8_EE5valuesr3std14is_convertibleIPA_NS3_14remove_pointerIDTcldtclsr3stdE7declvalISA_EE4dataEEE4typeEPA_S0_EE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalISA_EE4sizeEEmEE5valueEDnE4typeE:
  172|    927|        : m_data(other.data()), m_size(other.size()){}
_ZN4SpanIhEC2IhTnNSt3__19enable_ifIXsr3std14is_convertibleIPA_T_PA_hEE5valueEiE4typeELi0EEEPS4_m:
  119|  64.6k|    constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}
_ZN4SpanIKcEC2INSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEERKT_NS3_9enable_ifIXaaaantsr7is_SpanISA_EE5valuesr3std14is_convertibleIPA_NS3_14remove_pointerIDTcldtclsr3stdE7declvalISC_EE4dataEEE4typeEPA_S0_EE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalISC_EE4sizeEEmEE5valueEDnE4typeE:
  172|  8.19k|        : m_data(other.data()), m_size(other.size()){}
_ZN4SpanIKhEC2IhTnNSt3__19enable_ifIXsr3std14is_convertibleIPA_T_PA_S0_EE5valueEiE4typeELi0EEERKS_IS5_E:
  141|  64.6k|    constexpr Span(const Span<O>& other) noexcept : m_data(other.m_data), m_size(other.m_size) {}
miniscript.cpp:_ZNK4SpanINSt3__18optionalINS0_3setI7CPubKeyZNK10miniscript4NodeIS3_E17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS0_9allocatorIS3_EEEEEEE5beginEv:
  175|  54.9M|    constexpr C* begin() const noexcept { return m_data; }
miniscript.cpp:_ZNK4SpanINSt3__18optionalINS0_3setI7CPubKeyZNK10miniscript4NodeIS3_E17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS0_9allocatorIS3_EEEEEEE3endEv:
  176|  54.9M|    constexpr C* end() const noexcept { return m_data + m_size; }
miniscript.cpp:_ZN4SpanINSt3__18optionalINS0_3setI7CPubKeyZNK10miniscript4NodeIS3_E17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS0_9allocatorIS3_EEEEEEEC2INS0_6vectorISH_NSE_ISH_EEEEEERSA_NS0_9enable_ifIXaaaantsr7is_SpanISA_EE5valuesr3std14is_convertibleIPA_NS0_14remove_pointerIDTcldtclsr3stdE7declvalISN_EE4dataEEE4typeEPA_SH_EE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalISN_EE4sizeEEmEE5valueEDnE4typeE:
  165|  27.6M|        : m_data(other.data()), m_size(other.size()){}
miniscript.cpp:_ZNK4SpanINSt3__18optionalINS0_3setI7CPubKeyZNK10miniscript4NodeIS3_E17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS0_9allocatorIS3_EEEEEEE4lastEm:
  211|  27.6M|    {
  212|  27.6M|         ASSERT_IF_DEBUG(size() >= count);
  213|  27.6M|         return Span<C>(m_data + m_size - count, count);
  214|  27.6M|    }
miniscript.cpp:_ZN4SpanINSt3__18optionalINS0_3setI7CPubKeyZNK10miniscript4NodeIS3_E17DuplicateKeyCheckIN12_GLOBAL__N_113ParserContextEEEvRKT_E4CompNS0_9allocatorIS3_EEEEEEEC2ISH_TnNS0_9enable_ifIXsr3std14is_convertibleIPA_SA_PA_SH_EE5valueEiE4typeELi0EEEPSA_m:
  119|  27.6M|    constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}
_ZNK4SpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEixEm:
  191|  8.30M|    {
  192|  8.30M|        ASSERT_IF_DEBUG(size() > pos);
  193|  8.30M|        return m_data[pos];
  194|  8.30M|    }
_ZNK4SpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEE5beginEv:
  175|  2.79k|    constexpr C* begin() const noexcept { return m_data; }
_ZNK4SpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEE3endEv:
  176|  2.79k|    constexpr C* end() const noexcept { return m_data + m_size; }
_ZN4SpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEC2INS0_6vectorIS6_NS4_IS6_EEEEEERT_NS0_9enable_ifIXaaaantsr7is_SpanISC_EE5valuesr3std14is_convertibleIPA_NS0_14remove_pointerIDTcldtclsr3stdE7declvalISD_EE4dataEEE4typeEPA_S6_EE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalISD_EE4sizeEEmEE5valueEDnE4typeE:
  165|  13.8M|        : m_data(other.data()), m_size(other.size()){}
_ZNK4SpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEE4lastEm:
  211|  13.8M|    {
  212|  13.8M|         ASSERT_IF_DEBUG(size() >= count);
  213|  13.8M|         return Span<C>(m_data + m_size - count, count);
  214|  13.8M|    }
_ZN4SpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEC2IS6_TnNS0_9enable_ifIXsr3std14is_convertibleIPA_T_PA_S6_EE5valueEiE4typeELi0EEEPSA_m:
  119|  13.8M|    constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}
_ZNK4SpanIKcEixEm:
  191|   344M|    {
  192|   344M|        ASSERT_IF_DEBUG(size() > pos);
  193|   344M|        return m_data[pos];
  194|   344M|    }
_ZNK4SpanIKcE7subspanEm:
  196|  1.14M|    {
  197|  1.14M|        ASSERT_IF_DEBUG(size() >= offset);
  198|  1.14M|        return Span<C>(m_data + offset, m_size - offset);
  199|  1.14M|    }
_ZN4SpanIKcEC2IS0_TnNSt3__19enable_ifIXsr3std14is_convertibleIPA_T_PA_S0_EE5valueEiE4typeELi0EEEPS5_m:
  119|  1.14M|    constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}

_ZN18FuzzedDataProviderC2EPKhm:
   37|  5.47k|      : data_ptr_(data), remaining_bytes_(size) {}
_ZN18FuzzedDataProvider15ConsumeIntegralIhEET_v:
  195|  5.47k|template <typename T> T FuzzedDataProvider::ConsumeIntegral() {
  196|  5.47k|  return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
  197|  5.47k|                                std::numeric_limits<T>::max());
  198|  5.47k|}
_ZN18FuzzedDataProvider22ConsumeIntegralInRangeIhEET_S1_S1_:
  205|  5.47k|T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
  206|  5.47k|  static_assert(std::is_integral<T>::value, "An integral type is required.");
  207|  5.47k|  static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
  208|       |
  209|  5.47k|  if (min > max)
  ------------------
  |  Branch (209:7): [True: 0, False: 5.47k]
  ------------------
  210|      0|    abort();
  211|       |
  212|       |  // Use the biggest type possible to hold the range and the result.
  213|  5.47k|  uint64_t range = static_cast<uint64_t>(max) - static_cast<uint64_t>(min);
  214|  5.47k|  uint64_t result = 0;
  215|  5.47k|  size_t offset = 0;
  216|       |
  217|  10.9k|  while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
  ------------------
  |  Branch (217:10): [True: 5.47k, False: 5.47k]
  |  Branch (217:43): [True: 5.47k, False: 0]
  ------------------
  218|  10.9k|         remaining_bytes_ != 0) {
  ------------------
  |  Branch (218:10): [True: 5.47k, False: 0]
  ------------------
  219|       |    // Pull bytes off the end of the seed data. Experimentally, this seems to
  220|       |    // allow the fuzzer to more easily explore the input space. This makes
  221|       |    // sense, since it works by modifying inputs that caused new code to run,
  222|       |    // and this data is often used to encode length of data read by
  223|       |    // |ConsumeBytes|. Separating out read lengths makes it easier modify the
  224|       |    // contents of the data that is actually read.
  225|  5.47k|    --remaining_bytes_;
  226|  5.47k|    result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
  227|  5.47k|    offset += CHAR_BIT;
  228|  5.47k|  }
  229|       |
  230|       |  // Avoid division by 0, in case |range + 1| results in overflow.
  231|  5.47k|  if (range != std::numeric_limits<decltype(range)>::max())
  ------------------
  |  Branch (231:7): [True: 5.47k, False: 0]
  ------------------
  232|  5.47k|    result = result % (range + 1);
  233|       |
  234|  5.47k|  return static_cast<T>(static_cast<uint64_t>(min) + result);
  235|  5.47k|}
_ZN18FuzzedDataProvider15remaining_bytesEv:
   85|  5.47k|  size_t remaining_bytes() { return remaining_bytes_; }
_ZN18FuzzedDataProvider20ConsumeBytesAsStringEm:
  137|  5.47k|inline std::string FuzzedDataProvider::ConsumeBytesAsString(size_t num_bytes) {
  138|  5.47k|  static_assert(sizeof(std::string::value_type) == sizeof(uint8_t),
  139|  5.47k|                "ConsumeBytesAsString cannot convert the data to a string.");
  140|       |
  141|  5.47k|  num_bytes = std::min(num_bytes, remaining_bytes_);
  142|  5.47k|  std::string result(
  143|  5.47k|      reinterpret_cast<const std::string::value_type *>(data_ptr_), num_bytes);
  144|  5.47k|  Advance(num_bytes);
  145|  5.47k|  return result;
  146|  5.47k|}
_ZN18FuzzedDataProvider11ConsumeBoolEv:
  289|  5.47k|inline bool FuzzedDataProvider::ConsumeBool() {
  290|  5.47k|  return 1 & ConsumeIntegral<uint8_t>();
  291|  5.47k|}
_ZN18FuzzedDataProvider7AdvanceEm:
  344|  5.47k|inline void FuzzedDataProvider::Advance(size_t num_bytes) {
  345|  5.47k|  if (num_bytes > remaining_bytes_)
  ------------------
  |  Branch (345:7): [True: 0, False: 5.47k]
  ------------------
  346|      0|    abort();
  347|       |
  348|  5.47k|  data_ptr_ += num_bytes;
  349|  5.47k|  remaining_bytes_ -= num_bytes;
  350|  5.47k|}

LLVMFuzzerTestOneInput:
  222|  5.47k|{
  223|  5.47k|    test_one_input({data, size});
  224|  5.47k|    return 0;
  225|  5.47k|}
fuzz.cpp:_ZL14test_one_inputNSt3__14spanIKhLm18446744073709551615EEE:
   83|  5.47k|{
   84|  5.47k|    CheckGlobals check{};
   85|  5.47k|    (*Assert(g_test_one_input))(buffer);
  ------------------
  |  |   85|  5.47k|#define Assert(val) inline_assertion_check<true>(val, __FILE__, __LINE__, __func__, #val)
  ------------------
   86|  5.47k|}

_Z29miniscript_string_fuzz_targetNSt3__14spanIKhLm18446744073709551615EEE:
 1240|  5.47k|{
 1241|  5.47k|    if (buffer.empty()) return;
  ------------------
  |  Branch (1241:9): [True: 0, False: 5.47k]
  ------------------
 1242|  5.47k|    FuzzedDataProvider provider(buffer.data(), buffer.size());
 1243|  5.47k|    auto str = provider.ConsumeBytesAsString(provider.remaining_bytes() - 1);
 1244|  5.47k|    const ParserContext parser_ctx{(MsCtx)provider.ConsumeBool()};
 1245|  5.47k|    auto parsed = miniscript::FromString(str, parser_ctx);
 1246|  5.47k|    if (!parsed) return;
  ------------------
  |  Branch (1246:9): [True: 2.76k, False: 2.71k]
  ------------------
 1247|       |
 1248|  2.71k|    const auto str2 = parsed->ToString(parser_ctx);
 1249|  2.71k|    assert(str2);
 1250|  2.71k|    auto parsed2 = miniscript::FromString(*str2, parser_ctx);
 1251|  2.71k|    assert(parsed2);
 1252|  2.71k|    assert(*parsed == *parsed2);
 1253|  2.71k|}
miniscript.cpp:_ZNK12_GLOBAL__N_113ParserContext9MsContextEv:
  183|  43.0M|    MsCtx MsContext() const {
  184|  43.0M|        return script_ctx;
  185|  43.0M|    }
miniscript.cpp:_ZNK12_GLOBAL__N_113ParserContext10KeyCompareERK7CPubKeyS3_:
  123|   435k|    bool KeyCompare(const Key& a, const Key& b) const {
  124|   435k|        return a < b;
  125|   435k|    }
miniscript.cpp:_ZN12_GLOBAL__N_113ParserContextC2EN10miniscript17MiniscriptContextE:
  121|  5.47k|    constexpr ParserContext(MsCtx ctx) noexcept : script_ctx(ctx) {}
miniscript.cpp:_ZNK12_GLOBAL__N_113ParserContext8ToStringERK7CPubKey:
  128|  64.6k|    {
  129|  64.6k|        auto it = TEST_DATA.dummy_key_idx_map.find(key);
  130|  64.6k|        if (it == TEST_DATA.dummy_key_idx_map.end()) return {};
  ------------------
  |  Branch (130:13): [True: 0, False: 64.6k]
  ------------------
  131|  64.6k|        uint8_t idx = it->second;
  132|  64.6k|        return HexStr(Span{&idx, 1});
  133|  64.6k|    }
miniscript.cpp:_ZNK12_GLOBAL__N_113ParserContext10FromStringIPKcEENSt3__18optionalI7CPubKeyEET_S8_:
  153|   497k|    std::optional<Key> FromString(I first, I last) const {
  154|   497k|        if (last - first != 2) return {};
  ------------------
  |  Branch (154:13): [True: 115, False: 496k]
  ------------------
  155|   496k|        auto idx = ParseHex(std::string(first, last));
  156|   496k|        if (idx.size() != 1) return {};
  ------------------
  |  Branch (156:13): [True: 24, False: 496k]
  ------------------
  157|   496k|        return TEST_DATA.dummy_keys[idx[0]];
  158|   496k|    }

_ZN12CheckGlobalsC2Ev:
   56|  5.47k|CheckGlobals::CheckGlobals() : m_impl(std::make_unique<CheckGlobalsImpl>()) {}
_ZN12CheckGlobalsD2Ev:
   57|  5.47k|CheckGlobals::~CheckGlobals() = default;
_ZN16CheckGlobalsImplC2Ev:
   17|  5.47k|    {
   18|  5.47k|        g_used_g_prng = false;
   19|  5.47k|        g_seeded_g_prng_zero = false;
   20|  5.47k|        g_used_system_time = false;
   21|  5.47k|        SetMockTime(0s);
   22|  5.47k|    }
_ZN16CheckGlobalsImplD2Ev:
   24|  5.47k|    {
   25|  5.47k|        if (g_used_g_prng && !g_seeded_g_prng_zero) {
  ------------------
  |  Branch (25:13): [True: 0, False: 5.47k]
  |  Branch (25:30): [True: 0, False: 0]
  ------------------
   26|      0|            std::cerr << "\n\n"
   27|      0|                         "The current fuzz target used the global random state.\n\n"
   28|       |
   29|      0|                         "This is acceptable, but requires the fuzz target to call \n"
   30|      0|                         "SeedRandomStateForTest(SeedRand::ZEROS) in the first line \n"
   31|      0|                         "of the FUZZ_TARGET function.\n\n"
   32|       |
   33|      0|                         "An alternative solution would be to avoid any use of globals.\n\n"
   34|       |
   35|      0|                         "Without a solution, fuzz instability and non-determinism can lead \n"
   36|      0|                         "to non-reproducible bugs or inefficient fuzzing.\n\n"
   37|      0|                      << std::endl;
   38|      0|            std::abort(); // Abort, because AFL may try to recover from a std::exit
   39|      0|        }
   40|       |
   41|  5.47k|        if (g_used_system_time) {
  ------------------
  |  Branch (41:13): [True: 0, False: 5.47k]
  ------------------
   42|      0|            std::cerr << "\n\n"
   43|      0|                         "The current fuzz target accessed system time.\n\n"
   44|       |
   45|      0|                         "This is acceptable, but requires the fuzz target to call \n"
   46|      0|                         "SetMockTime() at the beginning of processing the fuzz input.\n\n"
   47|       |
   48|      0|                         "Without setting mock time, time-dependent behavior can lead \n"
   49|      0|                         "to non-reproducible bugs or inefficient fuzzing.\n\n"
   50|      0|                      << std::endl;
   51|      0|            std::abort();
   52|      0|        }
   53|  5.47k|    }

_Z22inline_check_non_fatalIbEOT_S1_PKciS3_S3_:
   35|  1.22k|{
   36|  1.22k|    if (!val) {
  ------------------
  |  Branch (36:9): [True: 0, False: 1.22k]
  ------------------
   37|      0|        throw NonFatalCheckError{assertion, file, line, func};
   38|      0|    }
   39|  1.22k|    return std::forward<T>(val);
   40|  1.22k|}
_Z22inline_check_non_fatalIRKbEOT_S3_PKciS5_S5_:
   35|  2.11k|{
   36|  2.11k|    if (!val) {
  ------------------
  |  Branch (36:9): [True: 0, False: 2.11k]
  ------------------
   37|      0|        throw NonFatalCheckError{assertion, file, line, func};
   38|      0|    }
   39|  2.11k|    return std::forward<T>(val);
   40|  2.11k|}
_Z22inline_assertion_checkILb1EbEOT0_S1_PKciS3_S3_:
   52|  5.47k|{
   53|  5.47k|    if (IS_ASSERT || std::is_constant_evaluated() || G_FUZZING
  ------------------
  |  Branch (53:9): [Folded - Ignored]
  |  Branch (53:22): [Folded - Ignored]
  |  Branch (53:54): [Folded - Ignored]
  ------------------
   54|       |#ifdef ABORT_ON_FAILED_ASSUME
   55|       |        || true
   56|       |#endif
   57|  5.47k|    ) {
   58|  5.47k|        if (!val) {
  ------------------
  |  Branch (58:13): [True: 0, False: 5.47k]
  ------------------
   59|      0|            assertion_fail(file, line, func, assertion);
   60|      0|        }
   61|  5.47k|    }
   62|  5.47k|    return std::forward<T>(val);
   63|  5.47k|}
_Z22inline_assertion_checkILb1ERPKNSt3__18functionIFvNS0_4spanIKhLm18446744073709551615EEEEEEEOT0_SB_PKciSD_SD_:
   52|  5.47k|{
   53|  5.47k|    if (IS_ASSERT || std::is_constant_evaluated() || G_FUZZING
  ------------------
  |  Branch (53:9): [Folded - Ignored]
  |  Branch (53:22): [Folded - Ignored]
  |  Branch (53:54): [Folded - Ignored]
  ------------------
   54|       |#ifdef ABORT_ON_FAILED_ASSUME
   55|       |        || true
   56|       |#endif
   57|  5.47k|    ) {
   58|  5.47k|        if (!val) {
  ------------------
  |  Branch (58:13): [True: 0, False: 5.47k]
  ------------------
   59|      0|            assertion_fail(file, line, func, assertion);
   60|      0|        }
   61|  5.47k|    }
   62|  5.47k|    return std::forward<T>(val);
   63|  5.47k|}

_Z5IsHexNSt3__117basic_string_viewIcNS_11char_traitsIcEEEE:
   42|  2.11k|{
   43|  4.25M|    for (char c : str) {
  ------------------
  |  Branch (43:17): [True: 4.25M, False: 2.07k]
  ------------------
   44|  4.25M|        if (HexDigit(c) < 0) return false;
  ------------------
  |  Branch (44:13): [True: 42, False: 4.25M]
  ------------------
   45|  4.25M|    }
   46|  2.07k|    return (str.size() > 0) && (str.size()%2 == 0);
  ------------------
  |  Branch (46:12): [True: 2.07k, False: 0]
  |  Branch (46:32): [True: 2.05k, False: 22]
  ------------------
   47|  2.11k|}
_Z11TryParseHexIhENSt3__18optionalINS0_6vectorIT_NS0_9allocatorIS3_EEEEEENS0_17basic_string_viewIcNS0_11char_traitsIcEEEE:
   51|   498k|{
   52|   498k|    std::vector<Byte> vch;
   53|   498k|    vch.reserve(str.size() / 2); // two hex characters form a single byte
   54|       |
   55|   498k|    auto it = str.begin();
   56|  2.45M|    while (it != str.end()) {
  ------------------
  |  Branch (56:12): [True: 1.95M, False: 498k]
  ------------------
   57|  1.95M|        if (IsSpace(*it)) {
  ------------------
  |  Branch (57:13): [True: 19, False: 1.95M]
  ------------------
   58|     19|            ++it;
   59|     19|            continue;
   60|     19|        }
   61|  1.95M|        auto c1 = HexDigit(*(it++));
   62|  1.95M|        if (it == str.end()) return std::nullopt;
  ------------------
  |  Branch (62:13): [True: 5, False: 1.95M]
  ------------------
   63|  1.95M|        auto c2 = HexDigit(*(it++));
   64|  1.95M|        if (c1 < 0 || c2 < 0) return std::nullopt;
  ------------------
  |  Branch (64:13): [True: 11, False: 1.95M]
  |  Branch (64:23): [True: 1, False: 1.95M]
  ------------------
   65|  1.95M|        vch.push_back(Byte(c1 << 4) | Byte(c2));
   66|  1.95M|    }
   67|   498k|    return vch;
   68|   498k|}

_Z7IsSpacec:
  166|  1.95M|constexpr inline bool IsSpace(char c) noexcept {
  167|  1.95M|    return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
  ------------------
  |  Branch (167:12): [True: 4, False: 1.95M]
  |  Branch (167:24): [True: 3, False: 1.95M]
  |  Branch (167:37): [True: 3, False: 1.95M]
  |  Branch (167:50): [True: 3, False: 1.95M]
  |  Branch (167:63): [True: 3, False: 1.95M]
  |  Branch (167:76): [True: 3, False: 1.95M]
  ------------------
  168|  1.95M|}
_Z8ParseHexIhENSt3__16vectorIT_NS0_9allocatorIS2_EEEENS0_17basic_string_viewIcNS0_11char_traitsIcEEEE:
   69|   498k|{
   70|   498k|    return TryParseHex<Byte>(hex_str).value_or(std::vector<Byte>{});
   71|   498k|}
_Z10ToIntegralIlENSt3__18optionalIT_EENS0_17basic_string_viewIcNS0_11char_traitsIcEEEE:
  180|  30.3k|{
  181|  30.3k|    static_assert(std::is_integral<T>::value);
  182|  30.3k|    T result;
  183|  30.3k|    const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result);
  184|  30.3k|    if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) {
  ------------------
  |  Branch (184:9): [True: 114, False: 30.2k]
  |  Branch (184:57): [True: 132, False: 30.1k]
  ------------------
  185|    246|        return std::nullopt;
  186|    246|    }
  187|  30.1k|    return result;
  188|  30.3k|}

_ZN4util8ToStringIjEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  234|  12.4k|{
  235|  12.4k|    std::ostringstream oss;
  236|  12.4k|    oss.imbue(std::locale::classic());
  237|  12.4k|    oss << t;
  238|  12.4k|    return oss.str();
  239|  12.4k|}

_Z11SetMockTimeNSt3__16chrono8durationIxNS_5ratioILl1ELl1EEEEE:
   42|  5.47k|{
   43|  5.47k|    Assert(mock_time_in >= 0s);
  ------------------
  |  |   85|  5.47k|#define Assert(val) inline_assertion_check<true>(val, __FILE__, __LINE__, __func__, #val)
  ------------------
   44|  5.47k|    g_mock_time.store(mock_time_in, std::memory_order_relaxed);
   45|  5.47k|}

_Z6VectorIJN10miniscript8internal6MaxIntIjEEEENSt3__16vectorINS4_11common_typeIJDpT_EE4typeENS4_9allocatorISA_EEEEDpOS7_:
   24|   292k|{
   25|   292k|    std::vector<typename std::common_type<Args...>::type> ret;
   26|   292k|    ret.reserve(sizeof...(args));
   27|       |    // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html
   28|   292k|    (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...};
   29|   292k|    return ret;
   30|   292k|}
_Z6VectorIJN10miniscript8internal7SatInfoEEENSt3__16vectorINS3_11common_typeIJDpT_EE4typeENS3_9allocatorIS9_EEEEDpOS6_:
   24|   146k|{
   25|   146k|    std::vector<typename std::common_type<Args...>::type> ret;
   26|   146k|    ret.reserve(sizeof...(args));
   27|       |    // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html
   28|   146k|    (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...};
   29|   146k|    return ret;
   30|   146k|}
_Z6VectorIJ7CPubKeyEENSt3__16vectorINS1_11common_typeIJDpT_EE4typeENS1_9allocatorIS7_EEEEDpOS4_:
   24|  37.3k|{
   25|  37.3k|    std::vector<typename std::common_type<Args...>::type> ret;
   26|  37.3k|    ret.reserve(sizeof...(args));
   27|       |    // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html
   28|  37.3k|    (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...};
   29|  37.3k|    return ret;
   30|  37.3k|}
_Z6VectorIJNSt3__110unique_ptrIKN10miniscript4NodeI7CPubKeyEENS0_14default_deleteIS6_EEEEEENS0_6vectorINS0_11common_typeIJDpT_EE4typeENS0_9allocatorISF_EEEEDpOSC_:
   24|  10.3M|{
   25|  10.3M|    std::vector<typename std::common_type<Args...>::type> ret;
   26|  10.3M|    ret.reserve(sizeof...(args));
   27|       |    // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html
   28|  10.3M|    (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...};
   29|  10.3M|    return ret;
   30|  10.3M|}
_Z6VectorIJNSt3__110unique_ptrIKN10miniscript4NodeI7CPubKeyEENS0_14default_deleteIS6_EEEES9_EENS0_6vectorINS0_11common_typeIJDpT_EE4typeENS0_9allocatorISF_EEEEDpOSC_:
   24|  16.2M|{
   25|  16.2M|    std::vector<typename std::common_type<Args...>::type> ret;
   26|  16.2M|    ret.reserve(sizeof...(args));
   27|       |    // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html
   28|  16.2M|    (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...};
   29|  16.2M|    return ret;
   30|  16.2M|}
_Z6VectorIJNSt3__110unique_ptrIKN10miniscript4NodeI7CPubKeyEENS0_14default_deleteIS6_EEEES9_S9_EENS0_6vectorINS0_11common_typeIJDpT_EE4typeENS0_9allocatorISF_EEEEDpOSC_:
   24|  8.99k|{
   25|  8.99k|    std::vector<typename std::common_type<Args...>::type> ret;
   26|  8.99k|    ret.reserve(sizeof...(args));
   27|       |    // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html
   28|  8.99k|    (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...};
   29|  8.99k|    return ret;
   30|  8.99k|}

