// File: sighingnow[P]compile-pascal/pl0_opt.cpp
// Function: pl0_block_helper(std::vector<TAC, std::allocator<TAC>>&, std::vector<BasicBlock, std::allocator<BasicBlock>>&, int, std::map<int, std::vector<int, std::allocator<int>>, std::less<int>, std::allocator<std::pair<int const, std::vector<int, std::allocator<int>>>>>&, std::map<int, std::vector<int, std::allocator<int>>, std::less<int>, std::allocator<std::pair<int const, std::vector<int, std::allocator<int>>>>>&)
static int pl0_block_helper(std::vector<TAC> & code, std::vector<BasicBlock> & bbs, int p,
        std::map<int, std::vector<int>> & pres, std::map<int, std::vector<int>> & sufs)
{
    BasicBlock header(0, false);
    while (code[p].op == "param" || code[p].op == "paramref") {
        header.push(code[p++]);
    }
    header.push(code[p++]); // function or procedure.
    while (code[p].op == "def" || code[p].op == "allocret") {
        header.push(code[p++]);
    }
    int hidx = bbs.size();
    bbs.emplace_back(header);
    while (code[p].op == "param" || code[p].op == "paramref"
            || code[p].op == "function" || code[p].op == "procedure") {
        p = pl0_block_helper(code, bbs, p, pres, sufs);
    }
    bbs[hidx].setBegin(code[p].rd->iv);

    while (code[p].op != "endproc" && code[p].op != "endfunc") {
        BasicBlock body(code[p].rd->iv, true);
        body.push(code[p++]);
        while (code[p].op != "goto" && code[p].op != "call"
                && code[p].op != "endproc" && code[p].op != "endfunc") {
            if (code[p].op == "cmp") {
                sufs[body.no].emplace_back(code[p].rd->iv);
                pres[code[p].rd->iv].emplace_back(body.no);
            }
            if (code[p].op == "def") {
                // add temporary variable to symbol table.
                bbs[hidx].push(code[p++]);
            }
            else {
                body.push(code[p++]);
            }
        }
        if (code[p].op == "goto") {
            // goto label
            sufs[body.no].emplace_back(code[p].rs->iv);
            pres[code[p].rs->iv].emplace_back(body.no);
            body.push(code[p++]);
        }
        else if (code[p].op == "call") {
            // call ... -> ...
            // label: 
            body.push(code[p++]);
            sufs[body.no].emplace_back(code[p].rd->iv);
            pres[code[p].rd->iv].emplace_back(body.no);
        }
        else {
            body.push(code[p]);
        }

        bbs.emplace_back(body);
    }
    bbs[hidx].setEnd(bbs.back().no);
    bbs.back().is_end = true;
    return (++p);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
leaq -0xe8(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0xceed0
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x25236(%rip), %rsi     # 0xf110b
callq 0x2a580
movb %al, -0x1b9(%rbp)
jmp 0xcbee2
movb -0x1b9(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x1ba(%rbp)
jne 0xcbf29
jmp 0xcbef7
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x251f4(%rip), %rsi     # 0xf1102
callq 0x2a580
movb %al, -0x1bb(%rbp)
jmp 0xcbf1b
movb -0x1bb(%rbp), %al
movb %al, -0x1ba(%rbp)
jmp 0xcbf29
movb -0x1ba(%rbp), %al
testb $0x1, %al
jne 0xcbf35
jmp 0xcbf76
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movl %esi, %eax
incl %eax
movl %eax, -0x14(%rbp)
callq 0xcceb0
movq %rax, %rsi
leaq -0xe8(%rbp), %rdi
callq 0xc9520
jmp 0xcbf5a
jmp 0xcbebe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
jmp 0xcc74f
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movl %esi, %eax
incl %eax
movl %eax, -0x14(%rbp)
callq 0xcceb0
movq %rax, %rsi
leaq -0xe8(%rbp), %rdi
callq 0xc9520
jmp 0xcbf9b
jmp 0xcbf9d
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x250f7(%rip), %rsi     # 0xf10ab
callq 0x2a580
movb %al, -0x1bc(%rbp)
jmp 0xcbfc1
movb -0x1bc(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x1bd(%rbp)
jne 0xcc008
jmp 0xcbfd6
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x2545d(%rip), %rsi     # 0xf144a
callq 0x2a580
movb %al, -0x1be(%rbp)
jmp 0xcbffa
movb -0x1be(%rbp), %al
movb %al, -0x1bd(%rbp)
jmp 0xcc008
movb -0x1bd(%rbp), %al
testb $0x1, %al
jne 0xcc014
jmp 0xcc03e
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movl %esi, %eax
incl %eax
movl %eax, -0x14(%rbp)
callq 0xcceb0
movq %rax, %rsi
leaq -0xe8(%rbp), %rdi
callq 0xc9520
jmp 0xcc039
jmp 0xcbf9d
movq -0x10(%rbp), %rdi
callq 0xce1a0
movl %eax, -0xf8(%rbp)
movq -0x10(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0xcef70
jmp 0xcc05f
jmp 0xcc061
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x25093(%rip), %rsi     # 0xf110b
callq 0x2a580
movb %al, -0x1bf(%rbp)
jmp 0xcc085
movb -0x1bf(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x1c0(%rbp)
jne 0xcc142
jmp 0xcc09e
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x2504d(%rip), %rsi     # 0xf1102
callq 0x2a580
movb %al, -0x1c1(%rbp)
jmp 0xcc0c2
movb -0x1c1(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x1c0(%rbp)
jne 0xcc142
jmp 0xcc0d7
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24fe1(%rip), %rsi     # 0xf10cf
callq 0x2a580
movb %al, -0x1c2(%rbp)
jmp 0xcc0fb
movb -0x1c2(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x1c0(%rbp)
jne 0xcc142
jmp 0xcc110
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x23ed9(%rip), %rsi     # 0xf0000
callq 0x2a580
movb %al, -0x1c3(%rbp)
jmp 0xcc134
movb -0x1c3(%rbp), %al
movb %al, -0x1c0(%rbp)
jmp 0xcc142
movb -0x1c0(%rbp), %al
testb $0x1, %al
jne 0xcc14e
jmp 0xcc17c
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
callq 0xcbe90
movl %eax, -0x1c8(%rbp)
jmp 0xcc16e
movl -0x1c8(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0xcc061
movq -0x10(%rbp), %rdi
movslq -0xf8(%rbp), %rsi
callq 0xceff0
movq %rax, -0x1d0(%rbp)
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq -0x1d0(%rbp), %rdi
movq 0x20(%rax), %rax
movl 0x4(%rax), %esi
callq 0xc98c0
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24ea1(%rip), %rsi     # 0xf106b
callq 0xc02b0
movb %al, -0x1d1(%rbp)
jmp 0xcc1d7
movb -0x1d1(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1d2(%rbp)
jne 0xcc1ec
jmp 0xcc21e
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24edd(%rip), %rsi     # 0xf10e0
callq 0xc02b0
movb %al, -0x1d3(%rbp)
jmp 0xcc210
movb -0x1d3(%rbp), %al
movb %al, -0x1d2(%rbp)
jmp 0xcc21e
movb -0x1d2(%rbp), %al
testb $0x1, %al
jne 0xcc22d
jmp 0xcc6ea
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq 0x20(%rax), %rax
movl 0x4(%rax), %esi
leaq -0x1b8(%rbp), %rdi
movl $0x1, %edx
callq 0xceed0
jmp 0xcc254
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movl %esi, %eax
incl %eax
movl %eax, -0x14(%rbp)
callq 0xcceb0
movq %rax, %rsi
leaq -0x1b8(%rbp), %rdi
callq 0xc9520
jmp 0xcc279
jmp 0xcc27b
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24f40(%rip), %rsi     # 0xf11d2
callq 0xc02b0
movb %al, -0x1d4(%rbp)
jmp 0xcc29f
movb -0x1d4(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1d5(%rbp)
jne 0xcc2b7
jmp 0xcc35b
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x23edd(%rip), %rsi     # 0xf01ab
callq 0xc02b0
movb %al, -0x1d6(%rbp)
jmp 0xcc2db
movb -0x1d6(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1d5(%rbp)
jne 0xcc2f0
jmp 0xcc35b
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24d64(%rip), %rsi     # 0xf106b
callq 0xc02b0
movb %al, -0x1d7(%rbp)
jmp 0xcc314
movb -0x1d7(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1d5(%rbp)
jne 0xcc329
jmp 0xcc35b
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24da0(%rip), %rsi     # 0xf10e0
callq 0xc02b0
movb %al, -0x1d8(%rbp)
jmp 0xcc34d
movb -0x1d8(%rbp), %al
movb %al, -0x1d5(%rbp)
jmp 0xcc35b
movb -0x1d5(%rbp), %al
testb $0x1, %al
jne 0xcc36a
jmp 0xcc4e2
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24e4d(%rip), %rsi     # 0xf11ce
callq 0x2a580
movb %al, -0x1d9(%rbp)
jmp 0xcc38e
movb -0x1d9(%rbp), %al
testb $0x1, %al
jne 0xcc39d
jmp 0xcc448
movq -0x28(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0xce0a0
movq %rax, -0x1e8(%rbp)
jmp 0xcc3b6
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq -0x1e8(%rbp), %rdi
movq 0x20(%rax), %rsi
addq $0x4, %rsi
callq 0xbfb80
jmp 0xcc3d9
movq -0x20(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq -0x1f8(%rbp), %rdi
movq 0x20(%rax), %rsi
addq $0x4, %rsi
callq 0xce0a0
movq %rax, -0x1f0(%rbp)
jmp 0xcc40e
movq -0x1f0(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0xcf010
jmp 0xcc423
jmp 0xcc448
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0xcf090
jmp 0xcc74f
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24c4c(%rip), %rsi     # 0xf10ab
callq 0x2a580
movb %al, -0x1f9(%rbp)
jmp 0xcc46c
movb -0x1f9(%rbp), %al
testb $0x1, %al
jne 0xcc478
jmp 0xcc4b6
movq -0x10(%rbp), %rdi
movslq -0xf8(%rbp), %rsi
callq 0xceff0
movq %rax, -0x208(%rbp)
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movl %esi, %eax
incl %eax
movl %eax, -0x14(%rbp)
callq 0xcceb0
movq -0x208(%rbp), %rdi
movq %rax, %rsi
callq 0xc9520
jmp 0xcc4b4
jmp 0xcc4dd
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movl %esi, %eax
incl %eax
movl %eax, -0x14(%rbp)
callq 0xcceb0
movq %rax, %rsi
leaq -0x1b8(%rbp), %rdi
callq 0xc9520
jmp 0xcc4db
jmp 0xcc4dd
jmp 0xcc27b
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x24cd9(%rip), %rsi     # 0xf11d2
callq 0x2a580
movb %al, -0x209(%rbp)
jmp 0xcc506
movb -0x209(%rbp), %al
testb $0x1, %al
jne 0xcc515
jmp 0xcc5c5
movq -0x28(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0xce0a0
movq %rax, -0x218(%rbp)
jmp 0xcc52e
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq -0x218(%rbp), %rdi
movq 0x28(%rax), %rsi
addq $0x4, %rsi
callq 0xbfb80
jmp 0xcc551
movq -0x20(%rbp), %rax
movq %rax, -0x228(%rbp)
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq -0x228(%rbp), %rdi
movq 0x28(%rax), %rsi
addq $0x4, %rsi
callq 0xce0a0
movq %rax, -0x220(%rbp)
jmp 0xcc586
movq -0x220(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0xcf010
jmp 0xcc59b
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movl %esi, %eax
incl %eax
movl %eax, -0x14(%rbp)
callq 0xcceb0
movq %rax, %rsi
leaq -0x1b8(%rbp), %rdi
callq 0xc9520
jmp 0xcc5c0
jmp 0xcc6c7
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rdi
leaq 0x23bcf(%rip), %rsi     # 0xf01ab
callq 0x2a580
movb %al, -0x229(%rbp)
jmp 0xcc5e9
movb -0x229(%rbp), %al
testb $0x1, %al
jne 0xcc5f8
jmp 0xcc6a5
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
movl %esi, %eax
incl %eax
movl %eax, -0x14(%rbp)
callq 0xcceb0
movq %rax, %rsi
leaq -0x1b8(%rbp), %rdi
callq 0xc9520
jmp 0xcc61d
movq -0x28(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0xce0a0
movq %rax, -0x238(%rbp)
jmp 0xcc636
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq -0x238(%rbp), %rdi
movq 0x20(%rax), %rsi
addq $0x4, %rsi
callq 0xbfb80
jmp 0xcc659
movq -0x20(%rbp), %rax
movq %rax, -0x248(%rbp)
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq -0x248(%rbp), %rdi
movq 0x20(%rax), %rsi
addq $0x4, %rsi
callq 0xce0a0
movq %rax, -0x240(%rbp)
jmp 0xcc68e
movq -0x240(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0xcf010
jmp 0xcc6a3
jmp 0xcc6c5
movq -0x8(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0xcceb0
movq %rax, %rsi
leaq -0x1b8(%rbp), %rdi
callq 0xc9520
jmp 0xcc6c3
jmp 0xcc6c5
jmp 0xcc6c7
movq -0x10(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0xcef70
jmp 0xcc6d9
leaq -0x1b8(%rbp), %rdi
callq 0xcf090
jmp 0xcc1b3
movq -0x10(%rbp), %rdi
movslq -0xf8(%rbp), %rsi
callq 0xceff0
movq %rax, -0x258(%rbp)
movq -0x10(%rbp), %rdi
callq 0xcf100
movq -0x258(%rbp), %rdi
movl (%rax), %esi
callq 0xc98e0
movq -0x10(%rbp), %rdi
callq 0xcf100
movb $0x1, 0x5(%rax)
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24c(%rbp)
movl %eax, -0x14(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xcf090
movl -0x24c(%rbp), %eax
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq
leaq -0xe8(%rbp), %rdi
callq 0xcf090
movq -0xf0(%rbp), %rdi
callq 0x55b0
nopw (%rax,%rax)