// File: /workspace/github_cpp_makefile_star2_O1/iPapatsoris[P]Maximum-Independent-Set/src/Graph.cpp
// Function: Graph::getFunnels(std::vector<Graph::Funnel, std::allocator<Graph::Funnel>>&, unsigned int const*, unsigned int*, Graph::Funnel*) const
bool Graph::getFunnels(vector<Funnel> &funnels, const uint32_t *measure, uint32_t *effectiveNode, Funnel *fourFunnel) const {
    GraphTraversal graphTraversal(*this);
    while (graphTraversal.curNode != NONE) {
        uint32_t nodeV = graphTraversal.curNode;
        uint32_t vDegree = getNodeDegree(nodeV);
        if (vDegree == 3 || vDegree == 4) {
            vector<uint32_t> neighborsV;
            gatherNeighbors(nodeV, neighborsV);
            for (uint32_t i = 0 ; i < neighborsV.size() ; i++) {
                uint32_t nodeA = neighborsV[i];
                uint32_t nodeB, nodeC, nodeD;
                if (i == 0) {
                    nodeB = neighborsV[1];
                    nodeC = neighborsV[2];
                    nodeD = (neighborsV.size() == 3 ? NONE : neighborsV[3]);
                } else if (i == 1) {
                    nodeB = neighborsV[0];
                    nodeC = neighborsV[2];
                    nodeD = (neighborsV.size() == 3 ? NONE : neighborsV[3]);
                } else if (i == 2) {
                    nodeB = neighborsV[0];
                    nodeC = neighborsV[1];
                    nodeD = (neighborsV.size() == 3 ? NONE : neighborsV[3]);
                } else {
                    nodeB = neighborsV[0];
                    nodeC = neighborsV[1];
                    nodeD = (neighborsV.size() == 3 ? NONE : neighborsV[2]);
                }
                if (edgeExists(nodeB, nodeC) && (vDegree == 3 || vDegree == 4 && edgeExists(nodeB, nodeD) && edgeExists(nodeC, nodeD)))  {
                    if (measure == NULL) {
                        funnels.push_back(Funnel(nodeA, nodeB, nodeC, nodeD, nodeV));
                        if (vDegree == 4 || (getNodeDegree(nodeA) == 4 && (getNodeDegree(nodeB) == 4 || getNodeDegree(nodeC) == 4))) {
                            return true;
                        }
                    } else {
                        uint32_t degree3NodesCount;
                        if (getNodeDegree(nodeA) == 3) {
                            degree3NodesCount++;
                        }
                        if (getNodeDegree(nodeB) == 3) {
                            degree3NodesCount++;
                        }
                        if (getNodeDegree(nodeC) == 3) {
                            degree3NodesCount++;
                        }
                        if (vDegree == 4 && getNodeDegree(nodeD) == 3) {
                            degree3NodesCount++;
                        }
                        if (degree3NodesCount >= 3) {
                            Graph newGraph = *this;
                            unordered_set<uint32_t> extendedGrandchildren;
                            goToNode(nodeV, graphTraversal);
                            getExtendedGrandchildren(graphTraversal, extendedGrandchildren);
                            extendedGrandchildren.insert(nodeV);
                            std::unordered_set<uint32_t> neighbors;
                            gatherAllNeighbors(extendedGrandchildren, neighbors);
                            unordered_set<uint32_t> *smaller = &neighbors;
                            unordered_set<uint32_t> *bigger = &extendedGrandchildren;
                            if (smaller->size() > bigger->size()) {
                                std::unordered_set<uint32_t> *tmp = smaller;
                                smaller = bigger;
                                bigger = tmp;
                            }
                            smaller->insert(bigger->begin(), bigger->end());
                            ReduceInfo dummy;
                            newGraph.remove(vector<uint32_t>(smaller->begin(), smaller->end()), dummy);
                            if (newGraph.getEffectiveNodeMeasure(*measure - 20) <= *measure - 20) {
                                *effectiveNode = nodeV;
                                return true;
                            }
                        }
                        Funnel funnel(nodeA, nodeB, nodeC, nodeD, nodeV);
                        if (vDegree == 4) {
                            *fourFunnel = funnel;
                            return true;
                        } else {
                            funnels.push_back(funnel);
                        }
                    }
                }
            }
        }
        getNextNode(graphTraversal);
    }
    return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %r8, 0x108(%rsp)
movq %rcx, 0x100(%rsp)
movq %rdx, %r12
movq %rsi, %rbx
movq %rdi, %r13
leaq 0x2c(%rsp), %rsi
movq $-0x1, (%rsi)
callq 0xc034
leaq 0x10(%rsp), %r14
movq %r12, 0x118(%rsp)
movq %rbx, 0x110(%rsp)
movl 0x2c(%rsp), %ebp
cmpl $-0x1, %ebp
je 0x5b26
movl %ebp, 0x10(%rsp)
movq %r13, %rdi
movq %r14, %rsi
callq 0xc98e
movq %rax, 0x20(%rsp)
addl $-0x3, %eax
cmpl $0x1, %eax
movl %ebp, 0x34(%rsp)
ja 0x5b06
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
movl $0xffffffff, 0x78(%rsp) # imm = 0xFFFFFFFF
movq %r13, %rdi
movq %r14, %rsi
leaq 0x40(%rsp), %rdx
xorl %ecx, %ecx
leaq 0x78(%rsp), %r8
callq 0xc714
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
subq %rax, %rcx
setne 0x3(%rsp)
leaq 0x8(%rsp), %r14
je 0x5ae7
xorl %ebp, %ebp
movl (%rax,%rbp,4), %edx
movl %edx, 0x18(%rsp)
cmpl $0x2, %ebp
je 0x55c7
cmpl $0x1, %ebp
je 0x55bc
testl %ebp, %ebp
jne 0x55e4
movl 0x4(%rax), %edx
jmp 0x55be
movl (%rax), %edx
movl %edx, 0x8(%rsp)
movl 0x8(%rax), %edx
jmp 0x55d0
movl (%rax), %edx
movl %edx, 0x8(%rsp)
movl 0x4(%rax), %edx
movl %edx, 0x4(%rsp)
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
cmpq $0xc, %rcx
je 0x55ff
movl 0xc(%rax), %edx
jmp 0x55ff
movl (%rax), %edx
movl %edx, 0x8(%rsp)
movl 0x4(%rax), %edx
movl %edx, 0x4(%rsp)
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
cmpq $0xc, %rcx
je 0x55ff
movl 0x8(%rax), %edx
movl %edx, 0xc(%rsp)
movq %r13, %rdi
movq %r14, %rsi
leaq 0x4(%rsp), %rdx
callq 0xc5e2
cmpl $-0x1, %eax
je 0x5aa5
cmpl $0x3, 0x20(%rsp)
jne 0x5827
testq %r12, %r12
je 0x586b
movq %r13, %rdi
leaq 0x18(%rsp), %rsi
callq 0xc98e
movl %eax, %r15d
movq %r13, %rdi
leaq 0x8(%rsp), %rsi
callq 0xc98e
movl %eax, %r14d
movq %r13, %rdi
leaq 0x4(%rsp), %rsi
callq 0xc98e
xorl %ecx, %ecx
cmpl $0x3, %r14d
sete %cl
xorl %edx, %edx
cmpl $0x3, %r15d
sete %dl
movl 0x38(%rsp), %esi
addl %edx, %esi
xorl %edx, %edx
cmpl $0x3, %eax
sete %dl
addl %ecx, %edx
addl %esi, %edx
cmpl $0x4, 0x20(%rsp)
jne 0x56a5
movl %edx, %r14d
movq %r13, %rdi
leaq 0xc(%rsp), %rsi
callq 0xc98e
xorl %ecx, %ecx
cmpl $0x3, %eax
sete %cl
movl %r14d, %edx
addl %ecx, %edx
movl %edx, 0x38(%rsp)
cmpl $0x3, %edx
leaq 0x8(%rsp), %r14
jb 0x5997
leaq 0x78(%rsp), %rdi
movq %r13, %rsi
callq 0x274c
leaq 0x150(%rsp), %rax
movq %rax, 0x120(%rsp)
movq $0x1, 0x128(%rsp)
leaq 0x130(%rsp), %rcx
xorps %xmm0, %xmm0
movups %xmm0, (%rcx)
movl $0x3f800000, 0x140(%rsp) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movq %r13, %rdi
leaq 0x10(%rsp), %rsi
leaq 0x2c(%rsp), %rdx
callq 0xc132
leaq 0x120(%rsp), %r14
movb $0x0, 0xc8(%rsp)
movq %r13, %rdi
leaq 0x2c(%rsp), %rsi
movq %r14, %rdx
xorl %ecx, %ecx
leaq 0xc8(%rsp), %r15
movq %r15, %r8
callq 0x3f60
movq %r14, 0xc8(%rsp)
movq %r14, %rdi
leaq 0x10(%rsp), %rsi
movq %r15, %rdx
callq 0xdc3e
leaq 0xf8(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq $0x1, 0xd0(%rsp)
leaq 0xd8(%rsp), %rcx
xorps %xmm0, %xmm0
movups %xmm0, (%rcx)
movl $0x3f800000, 0xe8(%rsp) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movl $0xffffffff, 0x60(%rsp) # imm = 0xFFFFFFFF
leaq 0x130(%rsp), %rbx
leaq 0xc8(%rsp), %rdx
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x57cd
leaq 0x8(%rbx), %rsi
movq %r13, %rdi
movq %r14, %rcx
leaq 0x60(%rsp), %r8
callq 0xe514
testb %al, %al
leaq 0xc8(%rsp), %rdx
jne 0x57a5
movq %r14, %rax
movq 0xe0(%rsp), %r14
movq 0x138(%rsp), %rbx
cmpq %rbx, %r14
movq %rdx, %r15
cmovaq %rax, %r15
leaq 0x130(%rsp), %rax
leaq 0xd8(%rsp), %rcx
cmovaq %rcx, %rax
movq (%rax), %r12
movq %r15, 0x60(%rsp)
testq %r12, %r12
je 0x58c6
leaq 0x8(%r12), %rsi
movq %r15, %rdi
leaq 0x60(%rsp), %rdx
callq 0xdc3e
movq (%r12), %r12
jmp 0x5806
cmpl $0x4, 0x20(%rsp)
jne 0x5aa5
movq %r13, %rdi
movq %r14, %rsi
leaq 0xc(%rsp), %rdx
callq 0xc5e2
cmpl $-0x1, %eax
je 0x5aa5
movq %r13, %rdi
leaq 0x4(%rsp), %rsi
leaq 0xc(%rsp), %rdx
callq 0xc5e2
cmpl $-0x1, %eax
jne 0x5627
jmp 0x5aa5
movl 0x18(%rsp), %eax
movl %eax, 0x78(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0x7c(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x80(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x84(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x88(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x5a5d
movl 0x88(%rsp), %eax
movl %eax, 0x10(%rsi)
movups 0x78(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x14, 0x8(%rbx)
jmp 0x5a6a
cmpq %rbx, %r14
movl $0x0, 0x3c(%rsp)
leaq 0xc8(%rsp), %rax
leaq 0x120(%rsp), %rcx
cmovaq %rcx, %rax
movq 0x10(%rax), %rsi
leaq 0x60(%rsp), %rbx
movq %rbx, %rdi
xorl %edx, %edx
leaq 0x1f(%rsp), %rcx
callq 0xc9dc
xorl %eax, %eax
movb %al, 0x17(%rsp)
movb %al, 0x16(%rsp)
leaq 0x78(%rsp), %rdi
movq %rbx, %rsi
leaq 0x3c(%rsp), %rdx
leaq 0x17(%rsp), %rcx
xorl %r8d, %r8d
leaq 0x16(%rsp), %r9
callq 0xc16e
movq 0x118(%rsp), %r12
movq 0x110(%rsp), %rbx
leaq 0x8(%rsp), %r14
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0x594a
callq 0x21a0
movl (%r12), %eax
addl $-0x14, %eax
movl %eax, 0x60(%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x5198
movl (%r12), %ecx
addl $-0x14, %ecx
cmpl %ecx, %eax
leaq 0xc8(%rsp), %rdi
jbe 0x5a31
callq 0xcff8
leaq 0x120(%rsp), %rdi
callq 0xcff8
leaq 0x78(%rsp), %rdi
callq 0x2950
movl 0x18(%rsp), %eax
movl %eax, 0x78(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0x7c(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x80(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x84(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x88(%rsp)
cmpl $0x4, 0x20(%rsp)
jne 0x5a07
movl 0x88(%rsp), %eax
movq 0x108(%rsp), %rcx
movl %eax, 0x10(%rcx)
movl 0x78(%rsp), %eax
movl %eax, (%rcx)
movl 0x7c(%rsp), %eax
movl %eax, 0x4(%rcx)
movl 0x80(%rsp), %eax
movl %eax, 0x8(%rcx)
movl 0x84(%rsp), %eax
movl %eax, 0xc(%rcx)
jmp 0x5ab6
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x5aa9
movl 0x88(%rsp), %eax
movl %eax, 0x10(%rsi)
movups 0x78(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x14, 0x8(%rbx)
jmp 0x5ab6
movl 0x10(%rsp), %eax
movq 0x100(%rsp), %rcx
movl %eax, (%rcx)
callq 0xcff8
leaq 0x120(%rsp), %rdi
callq 0xcff8
leaq 0x78(%rsp), %rdi
callq 0x2950
jmp 0x5abd
movq %rbx, %rdi
leaq 0x78(%rsp), %rdx
callq 0xe6b8
cmpl $0x4, 0x20(%rsp)
je 0x5abd
movq %r13, %rdi
leaq 0x18(%rsp), %rsi
callq 0xc98e
cmpl $0x4, %eax
jne 0x5aa5
movq %r13, %rdi
movq %r14, %rsi
callq 0xc98e
cmpl $0x4, %eax
je 0x5abd
movq %r13, %rdi
leaq 0x4(%rsp), %rsi
callq 0xc98e
cmpl $0x4, %eax
je 0x5abd
movb $0x1, %al
jmp 0x5abf
movq %rbx, %rdi
leaq 0x78(%rsp), %rdx
callq 0xe8c4
cmpl $0x4, 0x20(%rsp)
jne 0x5aa5
xorl %eax, %eax
testb %al, %al
je 0x5aeb
incl %ebp
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
subq %rax, %rcx
movq %rcx, %rdx
sarq $0x2, %rdx
cmpq %rbp, %rdx
seta 0x3(%rsp)
ja 0x55a2
xorl %ebp, %ebp
jmp 0x5af0
movl $0x1, %ebp
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x5aff
callq 0x21a0
testb $0x1, 0x3(%rsp)
jne 0x5b15
movq %r13, %rdi
leaq 0x2c(%rsp), %rsi
callq 0xc034
xorl %ebp, %ebp
testl %ebp, %ebp
leaq 0x10(%rsp), %r14
movl 0x34(%rsp), %ebp
je 0x5522
cmpl $-0x1, %ebp
setne %al
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x5b67
jmp 0x5b67
jmp 0x5b67
jmp 0x5b60
jmp 0x5b67
jmp 0x5b6e
jmp 0x5b6e
movq %rax, %rbx
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0x5b71
callq 0x21a0
jmp 0x5b71
movq %rax, %rbx
jmp 0x5b7e
jmp 0x5b67
movq %rax, %rbx
jmp 0x5b95
jmp 0x5b6e
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0xcff8
leaq 0x120(%rsp), %rdi
callq 0xcff8
leaq 0x78(%rsp), %rdi
callq 0x2950
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x5ba4
callq 0x21a0
movq %rbx, %rdi
callq 0x2320