// File: /workspace/github_c_makefile_star2_O2/ToniWestbrook[P]paladin/bwamem.c
// Function: mem_chain_flt
int mem_chain_flt(const mem_opt_t *opt, int n_chn, mem_chain_t *a)
{
	int i, k;
	kvec_t(int) chains = {0,0,0}; // this keeps int indices of the non-overlapping chains
	if (n_chn == 0) return 0; // no need to filter
	// compute the weight of each chain and drop chains with small weight
	for (i = k = 0; i < n_chn; ++i) {
		mem_chain_t *c = &a[i];
		c->first = -1; c->kept = 0;
		c->w = mem_chain_weight(c);
		if (c->w < opt->min_chain_weight) free(c->seeds);
		else a[k++] = *c;
	}
	n_chn = k;
	ks_introsort(mem_flt, n_chn, a);
	// pairwise chain comparisons
	a[0].kept = 3;
	kv_push(int, chains, 0);
	for (i = 1; i < n_chn; ++i) {
		int large_ovlp = 0;
		for (k = 0; k < chains.n; ++k) {
			int j = chains.a[k];
			int b_max = chn_beg(a[j]) > chn_beg(a[i])? chn_beg(a[j]) : chn_beg(a[i]);
			int e_min = chn_end(a[j]) < chn_end(a[i])? chn_end(a[j]) : chn_end(a[i]);
			if (e_min > b_max && (!a[j].is_alt || a[i].is_alt)) { // have overlap; don't consider ovlp where the kept chain is ALT while the current chain is primary
				int li = chn_end(a[i]) - chn_beg(a[i]);
				int lj = chn_end(a[j]) - chn_beg(a[j]);
				int min_l = li < lj? li : lj;
				if (e_min - b_max >= min_l * opt->mask_level && min_l < opt->max_chain_gap) { // significant overlap
					large_ovlp = 1;
					if (a[j].first < 0) a[j].first = i; // keep the first shadowed hit s.t. mapq can be more accurate
					if (a[i].w < a[j].w * opt->drop_ratio && a[j].w - a[i].w >= opt->min_seed_len<<1)
						break;
				}
			}
		}
		if (k == chains.n) {
			kv_push(int, chains, i);
			a[i].kept = large_ovlp? 2 : 3;
		}
	}
	for (i = 0; i < chains.n; ++i) {
		mem_chain_t *c = &a[chains.a[i]];
		if (c->first >= 0) a[c->first].kept = 1;
	}
	free(chains.a);
	for (i = k = 0; i < n_chn; ++i) { // don't extend more than opt->max_chain_extend .kept=1/2 chains
		if (a[i].kept == 0 || a[i].kept == 3) continue;
		if (++k >= opt->max_chain_extend) break;
	}
	for (; i < n_chn; ++i)
		if (a[i].kept < 3) a[i].kept = 0;
	for (i = k = 0; i < n_chn; ++i) { // free discarded chains
		mem_chain_t *c = &a[i];
		if (c->kept == 0) free(c->seeds);
		else a[k++] = a[i];
	}
	return k;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
testl %esi, %esi
je 0x14419
movq %rdx, %rbx
movq %rdi, %r14
xorl %r15d, %r15d
testl %esi, %esi
cmovlel %r15d, %esi
imulq $0x28, %rsi, %r13
xorl %edx, %edx
movq %rdx, 0x18(%rsp)
movslq %edx, %rax
movq %rax, 0x8(%rsp)
cmpq %r15, %r13
je 0x14139
leaq (%rbx,%r15), %r12
orl $-0x1, 0x8(%rbx,%r15)
movl 0x10(%rbx,%r15), %ebp
movl %ebp, %eax
andl $0x9fffffff, %eax       # imm = 0x9FFFFFFF
movl %eax, 0x10(%rbx,%r15)
movq %r12, %rdi
callq 0x12588
andl $0x1fffffff, %eax       # imm = 0x1FFFFFFF
andl $0x80000000, %ebp       # imm = 0x80000000
orl %eax, %ebp
movl %ebp, 0x10(%rbx,%r15)
cmpl 0x7c(%r14), %eax
jge 0x14106
movq 0x20(%rbx,%r15), %rdi
callq 0x3390
movq 0x18(%rsp), %rdx
jmp 0x14130
movq 0x8(%rsp), %rax
leal 0x1(%rax), %edx
imulq $0x28, %rax, %rax
movq 0x20(%r12), %rcx
movq %rcx, 0x20(%rbx,%rax)
movups (%r12), %xmm0
movups 0x10(%r12), %xmm1
movups %xmm1, 0x10(%rbx,%rax)
movups %xmm0, (%rbx,%rax)
addq $0x28, %r15
jmp 0x140a8
movq 0x8(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x13a00
orb $0x60, 0x13(%rbx)
leaq 0xf6fc(%rip), %rdx      # 0x23850
leaq 0xf7df(%rip), %r8       # 0x2393a
pushq $0x8
popq %rsi
xorl %edi, %edi
movl $0x1a6, %ecx            # imm = 0x1A6
callq 0x1e0b4
andl $0x0, (%rax)
pushq $0x2
popq %rcx
pushq $0x1
popq %rsi
movq %rsi, %r12
cmpq %r15, %rsi
jge 0x14319
movq %rcx, (%rsp)
movq %rsi, 0x10(%rsp)
imulq $0x28, %rsi, %rcx
movq %rcx, 0x20(%rsp)
leaq (%rbx,%rcx), %rsi
xorl %edx, %edx
xorl %r15d, %r15d
cmpq %rdx, %r12
je 0x14288
movslq (%rax,%rdx,4), %rcx
imulq $0x28, %rcx, %rdi
movq 0x20(%rbx,%rdi), %rcx
movl 0x8(%rcx), %r10d
movq 0x20(%rsi), %r8
movl 0x8(%r8), %r13d
cmpl %r13d, %r10d
movl %r13d, %r11d
cmovgl %r10d, %r11d
movslq (%rbx,%rdi), %r9
imulq $0x18, %r9, %rbp
movl -0xc(%rcx,%rbp), %r9d
addl -0x10(%rcx,%rbp), %r9d
movslq (%rsi), %rcx
imulq $0x18, %rcx, %rbp
movl -0xc(%r8,%rbp), %ecx
addl -0x10(%r8,%rbp), %ecx
cmpl %ecx, %r9d
movl %ecx, %ebp
cmovll %r9d, %ebp
subl %r11d, %ebp
jle 0x14280
addq %rbx, %rdi
movl 0x10(%rdi), %r8d
testl %r8d, %r8d
js 0x1427a
subl %r13d, %ecx
subl %r10d, %r9d
cmpl %r9d, %ecx
cmovll %ecx, %r9d
cvtsi2ss %ebp, %xmm0
cvtsi2ss %r9d, %xmm1
mulss 0x9c(%r14), %xmm1
ucomiss %xmm1, %xmm0
jb 0x14280
cmpl 0x90(%r14), %r9d
jge 0x14280
cmpl $0x0, 0x8(%rdi)
jns 0x14242
movq 0x10(%rsp), %rcx
movl %ecx, 0x8(%rdi)
movl 0x10(%rsi), %ecx
movl $0x1fffffff, %edi       # imm = 0x1FFFFFFF
andl %edi, %ecx
cvtsi2ss %ecx, %xmm0
andl %edi, %r8d
cvtsi2ss %r8d, %xmm1
mulss 0xa0(%r14), %xmm1
ucomiss %xmm0, %xmm1
pushq $0x1
popq %r15
jbe 0x14280
subl %ecx, %r8d
movl 0x78(%r14), %ecx
addl %ecx, %ecx
cmpl %ecx, %r8d
jl 0x14280
jmp 0x1428b
cmpl $0x0, 0x10(%rsi)
js 0x14207
incq %rdx
jmp 0x1419a
movq %r12, %rdx
cmpq %rdx, %r12
movq 0x10(%rsp), %rsi
jne 0x14308
movq (%rsp), %rcx
cmpq %rcx, %r12
jne 0x142d8
leaq (%rcx,%rcx), %r13
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %r13
leaq (,%r13,4), %rsi
movq %rax, %rdi
leaq 0xf592(%rip), %rdx      # 0x23850
movl $0x1ba, %ecx            # imm = 0x1BA
leaq 0xf670(%rip), %r8       # 0x2393a
callq 0x1e0b4
movq 0x10(%rsp), %rsi
movq %r13, (%rsp)
movl %esi, (%rax,%r12,4)
incq %r12
xorl %ecx, %ecx
testl %r15d, %r15d
sete %cl
shll $0x1d, %ecx
movq 0x20(%rsp), %r8
movl 0x10(%rbx,%r8), %edx
movl $0x9fffffff, %edi       # imm = 0x9FFFFFFF
andl %edi, %edx
addl %edx, %ecx
addl $0x40000000, %ecx       # imm = 0x40000000
movl %ecx, 0x10(%rbx,%r8)
movq (%rsp), %rcx
incq %rsi
movq 0x8(%rsp), %r15
jmp 0x14176
xorl %ecx, %ecx
movl $0x9fffffff, %edx       # imm = 0x9FFFFFFF
cmpq %rcx, %r12
je 0x14350
movslq (%rax,%rcx,4), %rsi
imulq $0x28, %rsi, %rsi
movslq 0x8(%rbx,%rsi), %rsi
testq %rsi, %rsi
js 0x1434b
imulq $0x28, %rsi, %rsi
movl 0x10(%rbx,%rsi), %edi
andl %edx, %edi
orl $0x20000000, %edi       # imm = 0x20000000
movl %edi, 0x10(%rbx,%rsi)
incq %rcx
jmp 0x14320
movq %rax, %rdi
callq 0x3390
xorl %eax, %eax
movq 0x18(%rsp), %rdi
testl %edi, %edi
cmovlel %eax, %edi
leaq 0x10(%rbx), %rcx
xorl %edx, %edx
cmpq %rax, %rdi
je 0x14392
movl (%rcx), %esi
shrl $0x1d, %esi
andl $0x3, %esi
je 0x14389
cmpl $0x3, %esi
je 0x14389
incl %edx
cmpl 0x80(%r14), %edx
jge 0x14395
incq %rax
addq $0x28, %rcx
jmp 0x1436a
movq %rdi, %rax
imulq $0x28, %rax, %rcx
addq %rbx, %rcx
addq $0x10, %rcx
cmpq %r15, %rax
jge 0x143c4
movl (%rcx), %edx
movl %edx, %esi
notl %esi
testl $0x60000000, %esi       # imm = 0x60000000
je 0x143bb
andl $0x9fffffff, %edx       # imm = 0x9FFFFFFF
movl %edx, (%rcx)
incq %rax
addq $0x28, %rcx
jmp 0x143a0
imulq $0x28, %rdi, %r14
leaq 0x20(%rbx), %r15
xorl %r12d, %r12d
xorl %ebp, %ebp
cmpq %r12, %r14
je 0x1441b
testb $0x60, -0xd(%r15,%r12)
je 0x1440a
leaq (%r15,%r12), %rax
addq $-0x20, %rax
movslq %ebp, %rcx
incl %ebp
imulq $0x28, %rcx, %rcx
movq 0x20(%rax), %rdx
movq %rdx, 0x20(%rbx,%rcx)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%rbx,%rcx)
movups %xmm0, (%rbx,%rcx)
jmp 0x14413
movq (%r15,%r12), %rdi
callq 0x3390
addq $0x28, %r12
jmp 0x143d1
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq