// File: /workspace/github_cpp_makefile_star2_O1/eniac[P]Mantis/src/compile/compile_p4.cpp
// Function: findMalleableUsage(std::vector<MblRefNode*, std::allocator<MblRefNode*>>, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, P4RMalleableValueNode*, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::equal_to<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, P4RMalleableValueNode*>>>, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, P4RMalleableFieldNode*, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::equal_to<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, P4RMalleableFieldNode*>>>, std::vector<AstNode*, std::allocator<AstNode*>>*, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::equal_to<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, int>>>*)
void findMalleableUsage(
            vector<MblRefNode*> mblRefs,
            const unordered_map<string, P4RMalleableValueNode*> mblValues,
            const unordered_map<string, P4RMalleableFieldNode*> mblFields,
            vector<AstNode*>* nodeArray,
            unordered_map<string, int>* mblUsage) {

    while (!mblRefs.empty()) {
        MblRefNode* varRef = mblRefs.front();
        mblRefs.erase(mblRefs.begin());

        string* varName = varRef->name_->word_;

        if(mblUsage->find(*varName) != mblUsage->end()) {
            continue;
        }

        // Find the usage index: 0 - ingress, 1 - egress, 2 - both
        bool in_ingress = false;
        bool in_egress = false;
        // One var could be used in multiple tbls
        for (auto node : *nodeArray) {
            // Though filter P4RMalleableTableNode, its table node is still searched
            if(typeContains(node, "TableNode") && !typeContains(node, "P4R")) {
                TableNode* table = dynamic_cast<TableNode*>(node);
                string table_name = *(table->name_->word_);

                // Try to determine if the table uses the mblRef
                bool useMblRef = false;
                if(table->toString().find(*varName) != string::npos) {
                    useMblRef = true;
                } else {
                    // Check if used actions
                    for (auto action : *table->actions_->list_) {
                        for (auto tmp_node : *nodeArray) {
                            if(typeContains(tmp_node, "ActionNode")) {
                                ActionNode* tmp_action_node = dynamic_cast<ActionNode*>(tmp_node);
                                string tmp_action_name = tmp_action_node->name_->toString();
                                if(tmp_action_name.compare(action->name_->toString())==0) {
                                    if(tmp_action_node->toString().find(*varName) != string::npos) {
                                        useMblRef = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if(useMblRef) {
                            break;
                        }                        
                    }
                }
                if(useMblRef) {
                    if(findTblInIng(table_name, *nodeArray)) {
                        in_ingress = true;
                    } else {
                        in_egress = true;
                    }
                }
            }
        }
        if(in_ingress && in_egress) {
            mblUsage->emplace(*varName, USAGE::BOTH);
        } else if (in_ingress) {
            mblUsage->emplace(*varName, USAGE::INGRESS);
        } else if (in_egress) {
            mblUsage->emplace(*varName, USAGE::EGRESS);
        } else {
            PANIC("Can not find the target mblRef %s usage\n", varName->c_str());
        }
    }
    PRINT_VERBOSE("mbl usage dict:\n");
    for (auto i : *mblUsage) {
        PRINT_VERBOSE("  %s : %d\n", i.first.c_str(), i.second);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %r8, -0x40(%rbp)
movq %rcx, -0x78(%rbp)
movq %rdi, %r13
movq (%rdi), %rdi
movq 0x8(%r13), %rdx
cmpq %rdx, %rdi
je 0x6482d
leaq -0x58(%rbp), %r14
movq %r13, -0xb0(%rbp)
movq (%rdi), %rbx
leaq 0x8(%rdi), %rsi
cmpq %rdx, %rsi
je 0x6442f
subq %rsi, %rdx
callq 0x2e690
addq $-0x8, 0x8(%r13)
movq 0x80(%rbx), %rax
movq 0x40(%rax), %r15
movq -0x40(%rbp), %rdi
movq %r15, %rsi
callq 0x635ae
testq %rax, %rax
leaq -0xa8(%rbp), %rbx
jne 0x6481c
movq %r15, -0x88(%rbp)
movq -0x78(%rbp), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rax
movq %rax, -0xb8(%rbp)
cmpq %rax, %rcx
je 0x647da
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movq %rcx, -0x70(%rbp)
movq (%rcx), %r15
movq %r15, %rdi
leaq 0x13755(%rip), %rsi     # 0x77bf1
callq 0x6f390
testb %al, %al
je 0x645cc
movq %r15, %rdi
leaq 0x13417(%rip), %rsi     # 0x778ca
callq 0x6f390
testb %al, %al
jne 0x645cc
testq %r15, %r15
je 0x644e2
movq %r15, %rdi
leaq 0x28161(%rip), %rsi     # 0x8c630
leaq 0x28972(%rip), %rdx     # 0x8ce48
xorl %ecx, %ecx
callq 0x2e430
movq %rax, %r15
jmp 0x644e5
xorl %r15d, %r15d
movq 0x40(%r15), %rax
movq 0x40(%rax), %rax
movq %r14, -0x68(%rbp)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq -0x68(%rbp), %rdi
callq 0x32f92
movq (%r15), %rax
movq %rbx, %rdi
movq %r15, %r12
movq %r15, %rsi
callq *(%rax)
movq -0x88(%rbp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rcx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x2e710
movq %rax, %r15
movq -0xa8(%rbp), %rdi
leaq -0x98(%rbp), %rax
cmpq %rax, %rdi
je 0x64545
callq 0x2e360
cmpq $-0x1, %r15
leaq -0xf0(%rbp), %r15
je 0x645e6
leaq -0xe0(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x68(%rbp), %rsi
movq -0x60(%rbp), %rdx
addq %rsi, %rdx
movq %r15, %rdi
callq 0x32f92
movq %r15, %rdi
movq -0x78(%rbp), %rsi
callq 0x707cb
movl %eax, %r15d
movq -0xf0(%rbp), %rdi
leaq -0xe0(%rbp), %rax
cmpq %rax, %rdi
je 0x6459e
callq 0x2e360
movl -0x34(%rbp), %ecx
movzbl %cl, %ecx
testb %r15b, %r15b
movl $0x1, %eax
cmovel %eax, %ecx
movl %ecx, -0x34(%rbp)
movl -0x30(%rbp), %ecx
movzbl %cl, %ecx
cmovnel %eax, %ecx
movl %ecx, -0x30(%rbp)
movq -0x68(%rbp), %rdi
cmpq %r14, %rdi
je 0x645cc
callq 0x2e360
movq -0x70(%rbp), %rcx
addq $0x8, %rcx
cmpq -0xb8(%rbp), %rcx
jne 0x6448b
jmp 0x647d2
movq 0x50(%r12), %rax
movq 0x40(%rax), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rax
movq %rcx, -0x80(%rbp)
movq %rax, -0xc0(%rbp)
cmpq %rax, %rcx
je 0x645be
xorl %r13d, %r13d
movq -0x78(%rbp), %rax
movq (%rax), %r14
movq 0x8(%rax), %rax
movq %rax, -0xd0(%rbp)
cmpq %rax, %r14
je 0x64799
movq -0x80(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xc8(%rbp)
addq $0x8, %r14
movl %r13d, %r12d
movq -0x8(%r14), %r15
movq %r15, %rdi
leaq 0x13328(%rip), %rsi     # 0x7796f
callq 0x6f390
testb %al, %al
je 0x646c9
movq %r15, %rdi
leaq 0x27fd6(%rip), %rsi     # 0x8c630
leaq 0x2888f(%rip), %rdx     # 0x8cef0
xorl %ecx, %ecx
callq 0x2e430
movq %rax, %r15
movq 0x40(%rax), %rsi
movq (%rsi), %rax
movq %rbx, %rdi
callq *(%rax)
movq -0xc8(%rbp), %rax
movq 0x40(%rax), %rsi
movq (%rsi), %rax
leaq -0x110(%rbp), %rdi
callq *(%rax)
movb %r12b, -0x29(%rbp)
movq -0xa0(%rbp), %r12
movq -0x108(%rbp), %r13
cmpq %r12, %r13
movq %r12, %rdx
cmovbq %r13, %rdx
testq %rdx, %rdx
je 0x646d7
movq -0x110(%rbp), %rsi
movq -0xa8(%rbp), %rdi
callq 0x2e3c0
testl %eax, %eax
sete %bl
jmp 0x646d9
movl %r12d, %eax
xorl %r12d, %r12d
movl %eax, %r13d
jmp 0x64776
movb $0x1, %bl
cmpq %r13, %r12
sete %r12b
movq -0x110(%rbp), %rdi
leaq -0x100(%rbp), %rax
cmpq %rax, %rdi
je 0x646f8
callq 0x2e360
andb %r12b, %bl
leaq -0xa8(%rbp), %rbx
je 0x64755
movq (%r15), %rax
leaq -0x110(%rbp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq *(%rax)
movq -0x88(%rbp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rcx
movq %r12, %rdi
xorl %edx, %edx
callq 0x2e710
movq %rax, %r15
movq -0x110(%rbp), %rdi
leaq -0x100(%rbp), %rax
cmpq %rax, %rdi
je 0x64749
callq 0x2e360
movb $0x1, %r13b
movb $0x1, %r12b
cmpq $-0x1, %r15
jne 0x6475e
xorl %r12d, %r12d
movb -0x29(%rbp), %al
movl %eax, %r13d
movq -0xa8(%rbp), %rdi
leaq -0x98(%rbp), %rax
cmpq %rax, %rdi
je 0x64776
callq 0x2e360
testb %r12b, %r12b
leaq -0xf0(%rbp), %r15
jne 0x64799
leaq 0x8(%r14), %rax
movl %r13d, %r12d
cmpq -0xd0(%rbp), %r14
movq %rax, %r14
jne 0x64639
testb $0x1, %r13b
jne 0x647b8
movq -0x80(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x80(%rbp)
cmpq -0xc0(%rbp), %rax
jne 0x64609
testb $0x1, %r13b
leaq -0x58(%rbp), %r14
movq -0xb0(%rbp), %r13
jne 0x64556
jmp 0x645be
movl -0x34(%rbp), %eax
movl -0x30(%rbp), %ecx
jmp 0x647de
xorl %eax, %eax
xorl %ecx, %ecx
testb $0x1, %cl
movq -0x88(%rbp), %rsi
je 0x647f7
testb $0x1, %al
je 0x64808
movl $0x2, -0x68(%rbp)
jmp 0x6480f
testb $0x1, %al
je 0x64888
movl $0x1, -0x68(%rbp)
jmp 0x6480f
movl $0x0, -0x68(%rbp)
movq -0x40(%rbp), %rdi
leaq -0x68(%rbp), %rdx
callq 0x6ee22
movq (%r13), %rdi
movq 0x8(%r13), %rdx
cmpq %rdx, %rdi
jne 0x6441b
movq -0x40(%rbp), %rax
movq 0x10(%rax), %r14
testq %r14, %r14
je 0x64876
leaq -0x58(%rbp), %r15
leaq -0x68(%rbp), %rbx
movq %r15, -0x68(%rbp)
movq 0x8(%r14), %rsi
movq 0x10(%r14), %rdx
addq %rsi, %rdx
movq %rbx, %rdi
callq 0x32f92
movl 0x28(%r14), %eax
movl %eax, -0x48(%rbp)
movq -0x68(%rbp), %rdi
cmpq %r15, %rdi
je 0x6486e
callq 0x2e360
movq (%r14), %r14
testq %r14, %r14
jne 0x64842
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rsi, %rdi
callq 0x2f08e
jmp 0x648aa
movq %rax, %rbx
movq -0xf0(%rbp), %rdi
leaq -0xe0(%rbp), %rax
cmpq %rax, %rdi
jne 0x648cb
jmp 0x648db
movq %rax, %rbx
jmp 0x648db
jmp 0x648b1
movq %rax, %rbx
movq -0xa8(%rbp), %rdi
leaq -0x98(%rbp), %rax
cmpq %rax, %rdi
leaq -0x58(%rbp), %r14
je 0x648db
callq 0x2e360
jmp 0x648db
jmp 0x648d4
movq %rax, %rbx
leaq -0x58(%rbp), %r14
movq -0x68(%rbp), %rdi
cmpq %r14, %rdi
je 0x648e9
callq 0x2e360
movq %rbx, %rdi
callq 0x2e730