// File: aalto-speech[P]ftk/src/FactorGraph.cc
// Function: FactorGraph::prune_and_create_arcs(std::vector<std::unordered_set<unsigned short, std::hash<unsigned short>, std::equal_to<unsigned short>, std::allocator<unsigned short>>, std::allocator<std::unordered_set<unsigned short, std::hash<unsigned short>, std::equal_to<unsigned short>, std::allocator<unsigned short>>>>&)
void
FactorGraph::prune_and_create_arcs(vector<unordered_set<fg_node_idx_t> > &incoming)
{
    // Find all possible node start positions
    unordered_set<int> possible_node_starts;
    possible_node_starts.insert(text.size());
    for (int i=incoming.size()-1; i>= 0; i--) {
        if (possible_node_starts.find(i) == possible_node_starts.end()) continue;
        for (auto it = incoming[i].cbegin(); it != incoming[i].cend(); ++it)
            possible_node_starts.insert(*it);
    }

    // Prune non-reachable nodes
    for (auto it = nodes.begin(); it != nodes.end(); ) {
        if (possible_node_starts.find(it->start_pos) == possible_node_starts.end() ||
            possible_node_starts.find(it->start_pos+it->len) == possible_node_starts.end())
            it = nodes.erase(it);
        else
            ++it;
    }

    // Add end node
    nodes.push_back(Node(text.size(),0));

    // Collect nodes by start position
    vector<vector<unsigned int> > nodes_by_start_pos(text.size()+1);
    for (unsigned int i=1; i<nodes.size(); i++)
        nodes_by_start_pos[nodes[i].start_pos].push_back(i);

    // Set arcs
    for (unsigned int i=0; i<nodes.size()-1; i++) {
        unsigned int end_pos = nodes[i].start_pos + nodes[i].len;
        for (unsigned int j=0; j<nodes_by_start_pos[end_pos].size(); j++) {
            unsigned int nodei = nodes_by_start_pos[end_pos][j];
            Arc *arc = new Arc(i, nodei, 0.0);
            arcs.push_back(arc);
            nodes[i].outgoing.push_back(arc);
            nodes[nodei].incoming.push_back(arc);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x190(%rbp)
leaq -0x48(%rbp), %rdi
movq %rdi, -0x188(%rbp)
callq 0x23640
movq -0x190(%rbp), %rdi
callq 0x42d0
movq -0x188(%rbp), %rdi
movl %eax, -0x4c(%rbp)
leaq -0x4c(%rbp), %rsi
callq 0x23660
movb %dl, -0x179(%rbp)
movq %rax, -0x178(%rbp)
jmp 0x218fc
movb -0x179(%rbp), %al
movq -0x178(%rbp), %rcx
movq %rcx, -0x70(%rbp)
movb %al, -0x68(%rbp)
movq -0x10(%rbp), %rdi
callq 0x236a0
subq $0x1, %rax
movl %eax, -0x74(%rbp)
cmpl $0x0, -0x74(%rbp)
jl 0x21a47
leaq -0x48(%rbp), %rdi
leaq -0x74(%rbp), %rsi
callq 0x23700
movq %rax, -0x198(%rbp)
jmp 0x21940
movq -0x198(%rbp), %rax
movq %rax, -0x80(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x23730
movq %rax, -0x88(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x236d0
testb $0x1, %al
jne 0x21971
jmp 0x21987
jmp 0x21a39
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x21f9d
movq -0x10(%rbp), %rdi
movslq -0x74(%rbp), %rsi
callq 0x234d0
movq %rax, %rdi
callq 0x23760
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
movslq -0x74(%rbp), %rsi
callq 0x234d0
movq %rax, %rdi
callq 0x237c0
movq %rax, -0x98(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x23790
testb $0x1, %al
jne 0x219d8
jmp 0x21a37
leaq -0x90(%rbp), %rdi
callq 0x237f0
movzwl (%rax), %eax
movl %eax, -0x9c(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x9c(%rbp), %rsi
callq 0x23660
movb %dl, -0x1a1(%rbp)
movq %rax, -0x1a0(%rbp)
jmp 0x21a0c
movb -0x1a1(%rbp), %al
movq -0x1a0(%rbp), %rcx
movq %rcx, -0xb0(%rbp)
movb %al, -0xa8(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x23820
jmp 0x219a3
jmp 0x21a39
movl -0x74(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x21920
movq -0x190(%rbp), %rdi
addq $0x40, %rdi
callq 0x23850
movq %rax, -0xb8(%rbp)
movq -0x190(%rbp), %rdi
addq $0x40, %rdi
callq 0x238c0
movq %rax, -0xc0(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x23880
testb $0x1, %al
jne 0x21a91
jmp 0x21c0c
leaq -0xb8(%rbp), %rdi
callq 0x238f0
movzwl (%rax), %eax
movl %eax, -0xcc(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0xcc(%rbp), %rsi
callq 0x23700
movq %rax, -0x1b0(%rbp)
jmp 0x21abf
movq -0x1b0(%rbp), %rax
movq %rax, -0xc8(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x23730
movq %rax, -0xd8(%rbp)
leaq -0xc8(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x236d0
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x1b1(%rbp)
jne 0x21b90
leaq -0xb8(%rbp), %rdi
movq %rdi, -0x1d0(%rbp)
callq 0x238f0
movq -0x1d0(%rbp), %rdi
movzwl (%rax), %eax
movl %eax, -0x1c4(%rbp)
callq 0x238f0
movq %rax, %rcx
movl -0x1c4(%rbp), %eax
movzbl 0x2(%rcx), %ecx
addl %ecx, %eax
movl %eax, -0xe4(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0xe4(%rbp), %rsi
callq 0x23700
movq %rax, -0x1c0(%rbp)
jmp 0x21b59
movq -0x1c0(%rbp), %rax
movq %rax, -0xe0(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x23730
movq %rax, -0xf0(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x236d0
movb %al, -0x1b1(%rbp)
movb -0x1b1(%rbp), %al
testb $0x1, %al
jne 0x21b9c
jmp 0x21bfb
movq -0x190(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x1e0(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x23980
movq -0x1e0(%rbp), %rdi
movq -0x100(%rbp), %rsi
callq 0x23910
movq %rax, -0x1d8(%rbp)
jmp 0x21bdd
movq -0x1d8(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0xf8(%rbp), %rax
movq %rax, -0xb8(%rbp)
jmp 0x21c07
leaq -0xb8(%rbp), %rdi
callq 0x239c0
jmp 0x21a5e
movq -0x190(%rbp), %rdi
movq %rdi, %rax
addq $0x40, %rax
movq %rax, -0x1e8(%rbp)
callq 0x42d0
movl %eax, %esi
leaq -0x138(%rbp), %rdi
xorl %edx, %edx
callq 0x233d0
jmp 0x21c38
movq -0x1e8(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x233a0
jmp 0x21c4d
leaq -0x138(%rbp), %rdi
callq 0x23420
movq -0x190(%rbp), %rdi
callq 0x42d0
incq %rax
movq %rax, -0x1f8(%rbp)
leaq -0x151(%rbp), %rdi
movq %rdi, -0x1f0(%rbp)
callq 0x239e0
movq -0x1f8(%rbp), %rsi
movq -0x1f0(%rbp), %rdx
leaq -0x150(%rbp), %rdi
callq 0x23a00
jmp 0x21c9e
leaq -0x151(%rbp), %rdi
callq 0x23a70
movl $0x1, -0x158(%rbp)
movq -0x190(%rbp), %rdi
movl -0x158(%rbp), %eax
movq %rax, -0x200(%rbp)
addq $0x40, %rdi
callq 0x23a90
movq %rax, %rcx
movq -0x200(%rbp), %rax
cmpq %rcx, %rax
jae 0x21d7c
movq -0x190(%rbp), %rdi
addq $0x40, %rdi
movl -0x158(%rbp), %eax
movl %eax, %esi
callq 0x23ae0
movzwl (%rax), %eax
movl %eax, %esi
leaq -0x150(%rbp), %rdi
callq 0x23ac0
movq %rax, %rdi
leaq -0x158(%rbp), %rsi
callq 0x23b00
jmp 0x21d1e
jmp 0x21d20
movl -0x158(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x158(%rbp)
jmp 0x21cb4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x23420
jmp 0x21f9d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x151(%rbp), %rdi
callq 0x23a70
jmp 0x21f9d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x21f91
movl $0x0, -0x15c(%rbp)
movq -0x190(%rbp), %rdi
movl -0x15c(%rbp), %eax
movq %rax, -0x208(%rbp)
addq $0x40, %rdi
callq 0x23a90
movq %rax, %rcx
movq -0x208(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x21f73
movq -0x190(%rbp), %rdi
addq $0x40, %rdi
movl -0x15c(%rbp), %eax
movl %eax, %esi
callq 0x23ae0
movq -0x190(%rbp), %rdi
movzwl (%rax), %eax
movl %eax, -0x20c(%rbp)
addq $0x40, %rdi
movl -0x15c(%rbp), %eax
movl %eax, %esi
callq 0x23ae0
movq %rax, %rcx
movl -0x20c(%rbp), %eax
movzbl 0x2(%rcx), %ecx
addl %ecx, %eax
movl %eax, -0x160(%rbp)
movl $0x0, -0x164(%rbp)
movl -0x164(%rbp), %eax
movq %rax, -0x218(%rbp)
movl -0x160(%rbp), %eax
movl %eax, %esi
leaq -0x150(%rbp), %rdi
callq 0x23ac0
movq %rax, %rdi
callq 0x23490
movq %rax, %rcx
movq -0x218(%rbp), %rax
cmpq %rcx, %rax
jae 0x21f5d
movl -0x160(%rbp), %eax
movl %eax, %esi
leaq -0x150(%rbp), %rdi
callq 0x23ac0
movq %rax, %rdi
movl -0x164(%rbp), %eax
movl %eax, %esi
callq 0x234b0
movl (%rax), %eax
movl %eax, -0x168(%rbp)
movl $0x10, %edi
callq 0x43d0
movq %rax, -0x220(%rbp)
jmp 0x21e8d
movq -0x220(%rbp), %rdi
movzwl -0x15c(%rbp), %esi
movzwl -0x168(%rbp), %edx
xorps %xmm0, %xmm0
callq 0x23b70
jmp 0x21eac
movq -0x190(%rbp), %rdi
movq -0x220(%rbp), %rax
movq %rax, -0x170(%rbp)
addq $0x58, %rdi
leaq -0x170(%rbp), %rsi
callq 0x23bb0
jmp 0x21ed3
movq -0x190(%rbp), %rdi
addq $0x40, %rdi
movl -0x15c(%rbp), %eax
movl %eax, %esi
callq 0x23ae0
movq %rax, %rdi
addq $0x20, %rdi
leaq -0x170(%rbp), %rsi
callq 0x23bb0
jmp 0x21f00
movq -0x190(%rbp), %rdi
addq $0x40, %rdi
movl -0x168(%rbp), %eax
movl %eax, %esi
callq 0x23ae0
movq %rax, %rdi
addq $0x8, %rdi
leaq -0x170(%rbp), %rsi
callq 0x23bb0
jmp 0x21f2d
jmp 0x21f2f
movl -0x164(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x164(%rbp)
jmp 0x21e12
movq -0x220(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
callq 0x43a0
jmp 0x21f91
jmp 0x21f5f
movl -0x15c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x15c(%rbp)
jmp 0x21d86
leaq -0x150(%rbp), %rdi
callq 0x23c20
leaq -0x48(%rbp), %rdi
callq 0x23c80
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq
leaq -0x150(%rbp), %rdi
callq 0x23c20
leaq -0x48(%rbp), %rdi
callq 0x23c80
movq -0x58(%rbp), %rdi
callq 0x46e0
nop