// File: /workspace/github_cpp_makefile_star2_O2/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, 0xc0(%rsp)
movq %rcx, 0xb8(%rsp)
movq %rdx, %rbx
movq %rsi, 0x40(%rsp)
movq %rdi, %r14
leaq 0x2c(%rsp), %rdi
movq %r14, %rsi
callq 0x270e
leaq 0x10(%rsp), %r12
leaq 0x50(%rsp), %r15
movq %rbx, 0x48(%rsp)
movq %r14, 0xc8(%rsp)
movl 0x2c(%rsp), %ebp
cmpl $-0x1, %ebp
je 0x4f91
movl %ebp, 0x10(%rsp)
movq %r14, %rdi
movq %r12, %rsi
callq 0xa5ce
movq %rax, 0x20(%rsp)
addl $-0x3, %eax
cmpl $0x1, %eax
ja 0x4f7a
andq $0x0, 0xb0(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0xa0(%rsp)
orl $-0x1, 0x50(%rsp)
movq %r14, %rdi
movq %r12, %rsi
leaq 0xa0(%rsp), %rdx
xorl %ecx, %ecx
movq %r15, %r8
callq 0xa3c8
movl %ebp, 0x34(%rsp)
movl $0x0, 0x28(%rsp)
xorl %ebp, %ebp
leaq 0x8(%rsp), %rbx
leaq 0x4(%rsp), %r15
movl %ebp, %ebp
movq 0xa0(%rsp), %rax
movq 0xa8(%rsp), %rcx
subq %rax, %rcx
movq %rcx, %r12
sarq $0x2, %r12
cmpq %rbp, %r12
jbe 0x4f56
movl (%rax,%rbp,4), %edx
movl %edx, 0x18(%rsp)
cmpq $0x2, %rbp
je 0x4b1d
cmpl $0x1, %ebp
je 0x4b12
testl %ebp, %ebp
jne 0x4b38
movl 0x4(%rax), %edx
jmp 0x4b14
movl (%rax), %edx
movl %edx, 0x8(%rsp)
movl 0x8(%rax), %edx
jmp 0x4b26
movl (%rax), %edx
movl %edx, 0x8(%rsp)
movl 0x4(%rax), %edx
movl %edx, 0x4(%rsp)
pushq $-0x1
popq %rdx
cmpq $0xc, %rcx
je 0x4b51
movl 0xc(%rax), %edx
jmp 0x4b51
movl (%rax), %edx
movl %edx, 0x8(%rsp)
movl 0x4(%rax), %edx
movl %edx, 0x4(%rsp)
pushq $-0x1
popq %rdx
cmpq $0xc, %rcx
je 0x4b51
movl 0x8(%rax), %edx
movl %edx, 0xc(%rsp)
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x9e3a
testb %al, %al
je 0x4ef2
cmpl $0x3, 0x20(%rsp)
jne 0x4e41
cmpq $0x0, 0x48(%rsp)
je 0x4e7e
movq %r14, %rdi
leaq 0x18(%rsp), %rsi
callq 0xa5ce
movl %eax, %ebx
movq %r14, %rdi
leaq 0x8(%rsp), %rsi
callq 0xa5ce
movl %eax, %r15d
movq %r14, %rdi
leaq 0x4(%rsp), %rsi
callq 0xa5ce
xorl %ecx, %ecx
cmpl $0x3, %r15d
sete %cl
xorl %edx, %edx
cmpl $0x3, %ebx
sete %dl
movl %r13d, %esi
addl %edx, %esi
xorl %r13d, %r13d
cmpl $0x3, %eax
sete %r13b
addl %ecx, %r13d
addl %esi, %r13d
cmpl $0x4, 0x20(%rsp)
jne 0x4bf3
movq %r14, %rdi
leaq 0xc(%rsp), %rsi
callq 0xa5ce
xorl %ecx, %ecx
cmpl $0x3, %eax
sete %cl
addl %ecx, %r13d
cmpl $0x3, %r13d
leaq 0x8(%rsp), %rbx
leaq 0x4(%rsp), %r15
jb 0x4dfa
movl %r13d, 0x38(%rsp)
leaq 0x50(%rsp), %rdi
movq %r14, %rsi
callq 0x251c
leaq 0x100(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq $0x1, 0xd8(%rsp)
leaq 0xe0(%rsp), %rcx
xorps %xmm0, %xmm0
movups %xmm0, (%rcx)
movl $0x3f800000, 0xf0(%rsp) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movq %r14, %rdi
leaq 0x10(%rsp), %rsi
leaq 0x2c(%rsp), %rdx
callq 0x9dde
leaq 0xd0(%rsp), %r13
movb $0x0, 0x120(%rsp)
movq %r14, %rdi
leaq 0x2c(%rsp), %rsi
movq %r13, %rdx
xorl %ecx, %ecx
leaq 0x120(%rsp), %r8
callq 0x3868
movq %r13, %rdi
leaq 0x10(%rsp), %rsi
callq 0xbc1a
movq %r14, %rdi
leaq 0x150(%rsp), %rax
movq %rax, 0x120(%rsp)
movq $0x1, 0x128(%rsp)
leaq 0x130(%rsp), %r14
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
movl $0x3f800000, 0x140(%rsp) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
orl $-0x1, 0x108(%rsp)
movq %r13, %rsi
leaq 0x120(%rsp), %r13
movq %r13, %rdx
leaq 0x108(%rsp), %rcx
callq 0xa61a
movq 0x138(%rsp), %rbx
movq 0xe8(%rsp), %r15
cmpq %r15, %rbx
movq %r13, %rdi
leaq 0xd0(%rsp), %rax
cmovaq %rax, %rdi
leaq 0xe0(%rsp), %rax
cmovaq %r14, %rax
movq (%rax), %rsi
xorl %edx, %edx
callq 0xc7c8
andl $0x0, 0x3c(%rsp)
cmpq %r15, %rbx
leaq 0xd0(%rsp), %rcx
cmovaq %rcx, %r13
movq 0x10(%r13), %rsi
leaq 0x108(%rsp), %r13
movq %r13, %rdi
xorl %edx, %edx
leaq 0x1f(%rsp), %rcx
callq 0xa660
xorl %eax, %eax
movb %al, 0x17(%rsp)
movb %al, 0x16(%rsp)
leaq 0x50(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
leaq 0x3c(%rsp), %rdx
leaq 0x17(%rsp), %rcx
xorl %r8d, %r8d
leaq 0x16(%rsp), %r9
callq 0x9e48
movq 0xc8(%rsp), %r14
movq %r13, %rdi
callq 0xb872
movq 0x48(%rsp), %rbx
movl (%rbx), %eax
addl $-0x14, %eax
movl %eax, 0x108(%rsp)
movq %r15, %rdi
movq %r13, %rsi
callq 0x4746
leaq 0x120(%rsp), %rdi
movl (%rbx), %ecx
addl $-0x14, %ecx
cmpl %ecx, %eax
leaq 0x8(%rsp), %rbx
leaq 0x4(%rsp), %r15
movl 0x38(%rsp), %r13d
jbe 0x4f25
callq 0xad26
leaq 0xd0(%rsp), %rdi
callq 0xad26
leaq 0x50(%rsp), %rdi
callq 0x269e
movl 0x18(%rsp), %eax
movl %eax, 0x50(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x58(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x5c(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x60(%rsp)
cmpl $0x4, 0x20(%rsp)
je 0x4ef9
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0xa692
jmp 0x4ef2
cmpl $0x4, 0x20(%rsp)
jne 0x4ef2
movq %r14, %rdi
movq %rbx, %rsi
leaq 0xc(%rsp), %rdx
callq 0x9e3a
testb %al, %al
je 0x4ef2
movq %r14, %rdi
movq %r15, %rsi
leaq 0xc(%rsp), %rdx
callq 0x9e3a
testb %al, %al
jne 0x4b76
jmp 0x4ef2
movl 0x18(%rsp), %eax
movl %eax, 0x50(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x58(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x5c(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x60(%rsp)
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0xc64a
cmpl $0x4, 0x20(%rsp)
je 0x4f4f
movq %r14, %rdi
leaq 0x18(%rsp), %rsi
callq 0xa5ce
cmpl $0x4, %eax
jne 0x4ef2
movq %r14, %rdi
movq %rbx, %rsi
callq 0xa5ce
cmpl $0x4, %eax
je 0x4f4f
movq %r14, %rdi
movq %r15, %rsi
callq 0xa5ce
cmpl $0x4, %eax
je 0x4f4f
incl %ebp
jmp 0x4ad2
movl 0x60(%rsp), %eax
movq 0xc0(%rsp), %rcx
movl %eax, 0x10(%rcx)
movl 0x50(%rsp), %eax
movl %eax, (%rcx)
movl 0x54(%rsp), %eax
movl %eax, 0x4(%rcx)
movl 0x58(%rsp), %eax
movl %eax, 0x8(%rcx)
movl 0x5c(%rsp), %eax
movl %eax, 0xc(%rcx)
jmp 0x4f4f
movl 0x10(%rsp), %eax
movq 0xb8(%rsp), %rcx
movl %eax, (%rcx)
callq 0xad26
leaq 0xd0(%rsp), %rdi
callq 0xad26
leaq 0x50(%rsp), %rdi
callq 0x269e
pushq $0x1
popq %rax
movl %eax, 0x28(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0xb872
cmpq %rbp, %r12
leaq 0x50(%rsp), %r15
movl 0x34(%rsp), %ebp
leaq 0x10(%rsp), %r12
movl 0x28(%rsp), %eax
ja 0x4f89
movq %r14, %rdi
leaq 0x2c(%rsp), %rsi
callq 0x9cf8
xorl %eax, %eax
testl %eax, %eax
je 0x4a5c
cmpl $-0x1, %ebp
setne %al
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x4ffb
jmp 0x4fc7
jmp 0x4ffb
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0xb872
jmp 0x4fca
jmp 0x4fc7
jmp 0x4fc7
jmp 0x4fdd
movq %rax, %rbx
leaq 0x120(%rsp), %rdi
callq 0xad26
jmp 0x4fe0
jmp 0x4ffb
jmp 0x4ffb
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0xad26
leaq 0x50(%rsp), %rdi
callq 0x269e
jmp 0x4ffe
jmp 0x4ffb
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0xb872
movq %rbx, %rdi
callq 0x22c0
nop