// File: ehw-fit[P]py-paretoarchive/src/paretoarchive/paretoarchive.h
// Function: BspTreeArchive<1>::checkDominance(BspTreeArchive<1>::Node*, ObjVec<1> const&, unsigned long, unsigned long)
int checkDominance(Node* node, ObjVec<OBJ> const& y, uint64_t B, uint64_t W)
	{
		static_assert(OBJ <= 63, "[checkDominance] the code supports 'only' up to 63 objectives");

#ifdef COUNTER
		cell_counter++;
#endif
		int ret = 0;

		if (node->leaf())
		{
			LeafNode* leaf = static_cast<LeafNode*>(node);

			for (unsigned int i=0; i<leaf->m_size; i++)
			{
				int d = ObjVec<OBJ>::dominance(leaf->m_point[i], y);
				if (d & 1)
				{
					assert(ret == 0);
					return -1;
				}
				else if (d == 2)
				{
					leaf->m_point[i] = leaf->m_point[leaf->m_size - 1];
					leaf->m_size--;
					i--;
					ret++;
				}
			}
		}
		else
		{
			InteriorNode* interior = static_cast<InteriorNode*>(node);

			uint64_t BB = B;
			uint64_t WW = W;
			if (y[interior->m_objective] < interior->m_threshold) BB |= (((uint64_t)1) << interior->m_objective);
			else WW |= (((uint64_t)1) << interior->m_objective);

			// recurse into left sub-tree
			if (WW == 0 || B == 0)
			{
				if (WW == (((uint64_t)1) << OBJ) - 1)
				{
					// point is dominated
					assert(ret == 0);
					return -1;
				}
				else
				{
					// recurse
					int result = checkDominance(interior->m_left, y, B, WW);
					if (result == -1)
					{
						assert(ret == 0);
						return -1;
					}
					if (result > 0)
					{
						ret += result;
						if (interior->m_left->empty())
						{
							delete interior->m_left;
							interior->m_left = nullptr;
						}
					}
				}
			}

			// recurse into right sub-tree
			if (W == 0 || BB == 0)
			{
				if (BB == (((uint64_t)1) << OBJ) - 1)
				{
					// whole space cell is dominated
					ret += interior->m_right->m_size;
					delete interior->m_right;
					interior->m_right = nullptr;
				}
				else
				{
					// recurse
					int result = checkDominance(interior->m_right, y, BB, W);
					if (result == -1)
					{
						assert(ret == 0);
						return -1;
					}
					if (result > 0)
					{
						ret += result;
						if (interior->m_right->empty())
						{
							delete interior->m_right;
							interior->m_right = nullptr;
						}
					}
				}
			}

			interior->m_size -= ret;

			if (ret > 0)
			{
				// make sure that the binary tree remains valid
				assert(interior->m_left || interior->m_right || interior->m_size == 0);
				Node* tmp = nullptr;
				if (! interior->m_right && interior->m_left) tmp = interior->m_left;
				else if (! interior->m_left && interior->m_right) tmp = interior->m_right;
				if (tmp)
				{
					assert(tmp->m_parent == node);
					assert(interior->m_size == tmp->m_size);

					// replace interior with tmp
					tmp->m_parent = interior->m_parent;
					if (interior->m_parent)
					{
						if (interior->m_parent->m_left == interior) interior->m_parent->m_left = tmp;
						else interior->m_parent->m_right = tmp;
					}
					else m_root = tmp;
					interior->m_left = nullptr;
					interior->m_right = nullptr;
					delete interior;
				}
			}
		}
		return ret;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x78(%rbp)
movl $0x0, -0x34(%rbp)
movq -0x18(%rbp), %rdi
callq 0x69540
testb $0x1, %al
jne 0x686e0
jmp 0x687a9
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x40(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jae 0x687a4
movq -0x40(%rbp), %rdi
addq $0x18, %rdi
movl -0x44(%rbp), %eax
shlq $0x4, %rax
addq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0x696b0
movl %eax, -0x48(%rbp)
movl -0x48(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x68734
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x68ab6
cmpl $0x2, -0x48(%rbp)
jne 0x68792
movq -0x40(%rbp), %rcx
addq $0x18, %rcx
movq -0x40(%rbp), %rax
movl 0x10(%rax), %eax
subl $0x1, %eax
movl %eax, %eax
shlq $0x4, %rax
addq %rax, %rcx
movq -0x40(%rbp), %rax
addq $0x18, %rax
movl -0x44(%rbp), %edx
shlq $0x4, %rdx
addq %rdx, %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x40(%rbp), %rax
movl 0x10(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x10(%rax)
movl -0x44(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x44(%rbp)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x68794
jmp 0x68796
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x686ef
jmp 0x68ab0
movq -0x18(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x20(%rbp), %rdi
movq -0x50(%rbp), %rax
movl 0x30(%rax), %esi
callq 0x69780
movsd (%rax), %xmm1
movq -0x50(%rbp), %rax
movsd 0x28(%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x687ff
movq -0x50(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
orq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x68818
movq -0x50(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
orq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0x6882a
cmpq $0x0, -0x28(%rbp)
jne 0x688bf
cmpq $0x1, -0x60(%rbp)
jne 0x6883d
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x68ab6
movq -0x78(%rbp), %rdi
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movq -0x60(%rbp), %r8
callq 0x686a0
movl %eax, -0x64(%rbp)
cmpl $-0x1, -0x64(%rbp)
jne 0x6886f
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x68ab6
cmpl $0x0, -0x64(%rbp)
jle 0x688bb
movl -0x64(%rbp), %eax
addl -0x34(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x697a0
testb $0x1, %al
jne 0x68891
jmp 0x688b9
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, %rax
je 0x688ad
movq -0x80(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq -0x50(%rbp), %rax
movq $0x0, 0x18(%rax)
jmp 0x688bb
jmp 0x688bd
jmp 0x688bf
cmpq $0x0, -0x30(%rbp)
je 0x688d1
cmpq $0x0, -0x58(%rbp)
jne 0x689a4
cmpq $0x1, -0x58(%rbp)
jne 0x6891c
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rax
movl 0x10(%rax), %eax
addl -0x34(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
je 0x6890b
movq -0x88(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq -0x50(%rbp), %rax
movq $0x0, 0x20(%rax)
jmp 0x689a2
movq -0x78(%rbp), %rdi
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rsi
movq -0x20(%rbp), %rdx
movq -0x58(%rbp), %rcx
movq -0x30(%rbp), %r8
callq 0x686a0
movl %eax, -0x68(%rbp)
cmpl $-0x1, -0x68(%rbp)
jne 0x6894e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x68ab6
cmpl $0x0, -0x68(%rbp)
jle 0x689a0
movl -0x68(%rbp), %eax
addl -0x34(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x697a0
testb $0x1, %al
jne 0x68970
jmp 0x6899e
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x90(%rbp)
cmpq $0x0, %rax
je 0x68992
movq -0x90(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq -0x50(%rbp), %rax
movq $0x0, 0x20(%rax)
jmp 0x689a0
jmp 0x689a2
jmp 0x689a4
movl -0x34(%rbp), %edx
movq -0x50(%rbp), %rax
movl 0x10(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x10(%rax)
cmpl $0x0, -0x34(%rbp)
jle 0x68aae
movq $0x0, -0x70(%rbp)
movq -0x50(%rbp), %rax
cmpq $0x0, 0x20(%rax)
jne 0x689e9
movq -0x50(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x689e9
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x70(%rbp)
jmp 0x68a0d
movq -0x50(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x68a0b
movq -0x50(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x68a0b
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x70(%rbp)
jmp 0x68a0d
cmpq $0x0, -0x70(%rbp)
je 0x68aac
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x70(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x50(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x68a69
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rax
cmpq -0x50(%rbp), %rax
jne 0x68a57
movq -0x70(%rbp), %rcx
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, 0x18(%rax)
jmp 0x68a67
movq -0x70(%rbp), %rcx
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, 0x20(%rax)
jmp 0x68a74
movq -0x78(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, (%rax)
movq -0x50(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x50(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x50(%rbp), %rax
movq %rax, -0x98(%rbp)
cmpq $0x0, %rax
je 0x68aaa
movq -0x98(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x68aac
jmp 0x68aae
jmp 0x68ab0
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)