// File: aalto-speech[P]ftk/src/EM.cc
// Function: forward(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, MultiStringFactorGraph const&, std::map<unsigned int, double, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, double>>>&)
flt_type
forward(const string &text,
        const MultiStringFactorGraph &msfg,
        map<msfg_node_idx_t, flt_type> &fw)
{
    map<msfg_node_idx_t, vector<MultiStringFactorGraph::Arc*> > arcs;
    msfg.collect_arcs(text, arcs);

    for (auto ndit = arcs.begin(); ndit != arcs.end(); ++ndit) {

        const MultiStringFactorGraph::Node &node = msfg.nodes[ndit->first];
        for (auto arc = node.outgoing.begin(); arc != node.outgoing.end(); ++arc) {
            int tgt_node = (**arc).target_node;
            flt_type cost = fw[ndit->first] + *(**arc).cost;
            if (fw.find(tgt_node) == fw.end()) fw[tgt_node] = cost;
            else fw[tgt_node] = add_log_domain_probs(fw[tgt_node], cost);
        }
    }

    return fw.at(msfg.string_end_nodes.at(text));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0x48(%rbp), %rdi
movq %rdi, -0xc0(%rbp)
callq 0x48dc0
movq -0xc0(%rbp), %rdx
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x2f320
jmp 0x450cd
leaq -0x48(%rbp), %rdi
callq 0x48de0
movq %rax, -0x60(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x3f270
movq %rax, -0x68(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x48e10
testb $0x1, %al
jne 0x450fd
jmp 0x4533f
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0xc8(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x48e40
movq -0xc8(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0x30c00
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
addq $0x50, %rdi
callq 0x30260
movq %rax, -0x78(%rbp)
movq -0x70(%rbp), %rdi
addq $0x50, %rdi
callq 0x302c0
movq %rax, -0x80(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x30290
testb $0x1, %al
jne 0x45161
jmp 0x4532f
leaq -0x78(%rbp), %rdi
callq 0x302f0
movq (%rax), %rax
movl 0x4(%rax), %eax
movl %eax, -0x84(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x48e40
movq -0xd8(%rbp), %rdi
movq %rax, %rsi
callq 0x48e60
movq %rax, -0xd0(%rbp)
jmp 0x451a2
movq -0xd0(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0xe8(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x302f0
movsd -0xe8(%rbp), %xmm0
movq (%rax), %rax
movq 0x8(%rax), %rax
movsd (%rax), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movq -0x18(%rbp), %rdi
movl -0x84(%rbp), %eax
movl %eax, -0x9c(%rbp)
leaq -0x9c(%rbp), %rsi
callq 0x48f70
movq %rax, -0xe0(%rbp)
jmp 0x45202
movq -0xe0(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x18(%rbp), %rdi
callq 0x48fa0
movq %rax, -0xa8(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x48f40
testb $0x1, %al
jne 0x45239
jmp 0x452a0
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0xf8(%rbp)
movq -0x18(%rbp), %rdi
movl -0x84(%rbp), %eax
movl %eax, -0xac(%rbp)
leaq -0xac(%rbp), %rsi
callq 0x48fd0
movq %rax, -0xf0(%rbp)
jmp 0x4526e
movq -0xf0(%rbp), %rax
movsd -0xf8(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0x4531f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x49150
jmp 0x453ad
movq -0x18(%rbp), %rdi
movl -0x84(%rbp), %eax
movl %eax, -0xb0(%rbp)
leaq -0xb0(%rbp), %rsi
callq 0x48fd0
movq %rax, -0x100(%rbp)
jmp 0x452c5
movq -0x100(%rbp), %rax
movsd (%rax), %xmm0
movsd -0x90(%rbp), %xmm1
callq 0x412e0
movsd %xmm0, -0x108(%rbp)
jmp 0x452e7
movq -0x18(%rbp), %rdi
movl -0x84(%rbp), %eax
movl %eax, -0xb4(%rbp)
leaq -0xb4(%rbp), %rsi
callq 0x48fd0
movq %rax, -0x110(%rbp)
jmp 0x4530c
movq -0x110(%rbp), %rax
movsd -0x108(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0x45321
leaq -0x78(%rbp), %rdi
callq 0x30320
jmp 0x4513a
jmp 0x45331
leaq -0x60(%rbp), %rdi
callq 0x400d0
jmp 0x450da
movq -0x18(%rbp), %rax
movq %rax, -0x120(%rbp)
movq -0x10(%rbp), %rdi
addq $0x38, %rdi
movq -0x8(%rbp), %rsi
callq 0x30970
movq %rax, -0x118(%rbp)
jmp 0x45364
movq -0x118(%rbp), %rsi
movq -0x120(%rbp), %rdi
callq 0x490b0
movq %rax, -0x128(%rbp)
jmp 0x45380
movq -0x128(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x130(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x49150
movsd -0x130(%rbp), %xmm0
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x46e0
nopw %cs:(%rax,%rax)