// File: aalto-speech[P]ftk/src/EM.cc
// Function: forward(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, double>>> const&, MultiStringFactorGraph const&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&, bool)
flt_type
forward(const map<string, flt_type> &words,
        const MultiStringFactorGraph &msfg,
        const set<string> &words_to_fb,
        bool full_forward_pass)
{
    flt_type total_lp = 0.0;

    if (full_forward_pass) {
        vector<flt_type> fw;
        forward(msfg, fw);
        for (auto wit = words_to_fb.cbegin(); wit != words_to_fb.cend(); ++wit)
            total_lp += words.at(*wit) * fw.at(msfg.string_end_nodes.at(*wit));
    }
    else {
        for (auto wit = words_to_fb.cbegin(); wit != words_to_fb.cend(); ++wit) {
            map<msfg_node_idx_t, flt_type> fw;
            total_lp += words.at(*wit) * forward(*wit, msfg, fw);
        }
    }

    return total_lp;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movb %cl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x28(%rbp)
testb $0x1, -0x19(%rbp)
je 0x45529
leaq -0x40(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0x49170
movq -0xa8(%rbp), %rsi
movq -0x10(%rbp), %rdi
callq 0x44eb0
jmp 0x45412
movq -0x18(%rbp), %rdi
callq 0x49190
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rdi
callq 0x491c0
movq %rax, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x235b0
testb $0x1, %al
jne 0x45442
jmp 0x4551b
movq -0x8(%rbp), %rax
movq %rax, -0xb8(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x491f0
movq -0xb8(%rbp), %rdi
movq %rax, %rsi
callq 0x48880
movq %rax, -0xb0(%rbp)
jmp 0x4546e
movq -0xb0(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0xd0(%rbp)
movq -0x10(%rbp), %rax
addq $0x38, %rax
movq %rax, -0xc8(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x491f0
movq -0xc8(%rbp), %rdi
movq %rax, %rsi
callq 0x30970
movq %rax, -0xc0(%rbp)
jmp 0x454b1
movq -0xc0(%rbp), %rax
movl (%rax), %eax
movl %eax, %esi
leaq -0x40(%rbp), %rdi
callq 0x49220
movq %rax, -0xd8(%rbp)
jmp 0x454ce
movsd -0xd0(%rbp), %xmm0
movq -0xd8(%rbp), %rax
movsd (%rax), %xmm2
movsd -0x28(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x49260
jmp 0x4541f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x48320
jmp 0x45630
leaq -0x40(%rbp), %rdi
callq 0x48320
jmp 0x45622
movq -0x18(%rbp), %rdi
callq 0x49190
movq %rax, -0x68(%rbp)
movq -0x18(%rbp), %rdi
callq 0x491c0
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x235b0
testb $0x1, %al
jne 0x45559
jmp 0x45620
leaq -0xa0(%rbp), %rdi
callq 0x49290
movq -0x8(%rbp), %rax
movq %rax, -0xe8(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x491f0
movq -0xe8(%rbp), %rdi
movq %rax, %rsi
callq 0x48880
movq %rax, -0xe0(%rbp)
jmp 0x45591
movq -0xe0(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0xf8(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x491f0
movq %rax, %rdi
movq -0x10(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
callq 0x45090
movsd %xmm0, -0xf0(%rbp)
jmp 0x455ca
movsd -0xf0(%rbp), %xmm2
movsd -0xf8(%rbp), %xmm0
movsd -0x28(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x492b0
leaq -0x68(%rbp), %rdi
callq 0x49260
jmp 0x45536
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x492b0
jmp 0x45630
jmp 0x45622
movsd -0x28(%rbp), %xmm0
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x46e0
nopl (%rax)