// File: /workspace/github_c_makefile_star2_O0/oridb[P]mc/mi/match.c
// Function: compile
static Dtree *
compile(Frontier **frontier, size_t nfrontier)
{
	size_t i, j, k;
	Dtree *dt, *out, **edge, *any;
	Frontier *fs, **row, **defaults ;
	Node **cs, **pat;
	Slot *slot, *s;
	size_t ncs, ncons, nrow, nedge, ndefaults, npat;

	assert(nfrontier > 0);

	fs = frontier[0];

	/* scan constructors horizontally */
	ncons = 0;
	for (i = 0; i < fs->nslot; i++) {
		switch (exprop(fs->slot[i]->pat)) {
		case Ovar:
		case Ogap:
			break;
		default:
			ncons++;
		}
	}
	if (ncons == 0) {
		fs->final->refcnt++;
		return fs->final;
	}

	assert(fs->nslot > 0);

	/* NOTE:
	 * at the moment we have not implemented any smarter heuristics described in the papers.
	 * we always select the first found constructor, i.e. the top-left one.
	 */

	slot = NULL;
	for (i = 0; i < fs->nslot; i++) {
		switch (exprop(fs->slot[i]->pat)) {
		case Ovar:
		case Ogap:
			continue;
		default:
			slot = fs->slot[i];
			goto pi_found;
		}
	}

pi_found:
	/* scan constructors vertically at pi to create the set 'CS' */
	cs = NULL;
	ncs = 0;
	for (i = 0; i < nfrontier; i++) {
		fs = frontier[i];
		for (j = 0; j < fs->nslot; j++) {
			s = fs->slot[j];
			switch (exprop(s->pat)) {
			case Ovar:
			case Ogap:
				break;
			case Olit:
				if (patheq(slot->path, s->path)) {
					/* NOTE:
					 * we could use a hash table, but given that the n is usually small,
					 * an exhaustive search would suffice.
					 */
					/* look for a duplicate entry to skip it; we want a unique set of constructors. */
					for (k = 0; k < ncs; k++) {
						if (pateq(cs[k], s->pat))
							break;
					}
					if (ncs == 0 || k == ncs)
						lappend(&cs, &ncs, s->pat);
				}
				break;
			default:
				assert(0);
			}
		}
	}
	/* project a new frontier for each selected constructor */
	edge = NULL;
	nedge = 0;
	pat = NULL;
	npat = 0;
	for (i = 0; i < ncs; i++) {
		row = NULL;
		nrow = 0;
		for (j = 0; j < nfrontier; j++) {
			fs = frontier[j];
			fs = project(cs[i], slot->path, slot->load, frontier[j]);
			if (fs != NULL)
				lappend(&row, &nrow, fs);
		}

		if (nrow > 0) {
			dt = compile(row, nrow);
			lappend(&edge, &nedge, dt);
			lappend(&pat, &npat, cs[i]);
		}
	}

	/* compile the defaults */
	defaults = NULL;
	ndefaults = 0;
	for (i = 0; i < nfrontier; i++) {
		fs = frontier[i];
		k = -1;
		for (j = 0; j < fs->nslot; j++) {
			/* locate the occurrence of pi in fs */
			if (patheq(slot->path, fs->slot[j]->path))
				k = j;
		}

		if (k == -1 || exprop(fs->slot[k]->pat) == Ovar || exprop(fs->slot[k]->pat) == Ogap)
			lappend(&defaults, &ndefaults, fs);
	}
	if (ndefaults)
		any = compile(defaults, ndefaults);
	else
		any = NULL;

	/* construct the result dtree */
	out = NULL;

	/* TODO
	 * use a hash table to avoid the quadratic complexity
	 * when we have a large N and the bottleneck becomes obvious.
	 */
	for (i = 0; i < ndtree; i++) {
		if (!dtree[i]->accept && dtreusable(dtree[i], slot->load, pat, npat, edge, nedge, any)) {
			out = dtree[i];
			out->refcnt++;
			break;
		}
	}
	if (out == NULL) {
		out = mkdtree(slot->pat->loc, genlbl(slot->pat->loc));
		out->refcnt++;
	}

	out->load = slot->load;
	out->npat = npat,
	out->pat = pat,
	out->nnext = nedge;
	out->next = edge;
	out->any = any;

	switch (exprop(slot->load)) {
	case Outag:
		out->nconstructors = nconstructors(tybase(exprtype(slot->load->expr.args[0])));
		break;
	case Oudata:
	case Omemb:
	case Otupget:
	case Oidx:
	case Oderef:
	case Ovar:
		out->nconstructors = nconstructors(tybase(exprtype(slot->load)));
		break;
	default:
		fatal(slot->pat, "unsupported pattern %s of type %s", opstr[exprop(slot->pat)], tystr(exprtype(slot->pat)));
	}
	return out;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jbe 0x451ec
jmp 0x4520b
leaq 0x10492(%rip), %rdi     # 0x55685
leaq 0x102bb(%rip), %rsi     # 0x554b5
movl $0x2a1, %edx            # imm = 0x2A1
leaq 0x1048d(%rip), %rcx     # 0x55693
callq 0x6160
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq $0x0, -0x98(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jae 0x4527e
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdi
callq 0x2f210
addl $-0x33, %eax
subl $0x1, %eax
ja 0x4525c
jmp 0x4525a
jmp 0x4526e
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x45270
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x45229
cmpq $0x0, -0x98(%rbp)
jne 0x452ad
movq -0x58(%rbp), %rax
movq 0x30(%rax), %rax
movq 0x68(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x68(%rax)
movq -0x58(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x4598f
movq -0x58(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jbe 0x452ba
jmp 0x452d9
leaq 0x103f6(%rip), %rdi     # 0x556b7
leaq 0x101ed(%rip), %rsi     # 0x554b5
movl $0x2b5, %edx            # imm = 0x2B5
leaq 0x103bf(%rip), %rcx     # 0x55693
callq 0x6160
movq $0x0, -0x80(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jae 0x45340
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdi
callq 0x2f210
addl $-0x33, %eax
subl $0x1, %eax
ja 0x4531c
jmp 0x4531a
jmp 0x45332
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x80(%rbp)
jmp 0x45342
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x452e9
jmp 0x45342
movq $0x0, -0x70(%rbp)
movq $0x0, -0x90(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x454c3
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x58(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jae 0x454b0
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x2f210
movl %eax, %ecx
movl %ecx, %eax
addl $-0x33, %eax
movl %ecx, -0xbc(%rbp)
subl $0x2, %eax
jb 0x453e0
jmp 0x453d0
movl -0xbc(%rbp), %eax
subl $0x35, %eax
je 0x453e5
jmp 0x4547e
jmp 0x4549d
movq -0x80(%rbp), %rax
movq (%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rsi
callq 0x47220
cmpl $0x0, %eax
je 0x4547c
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x90(%rbp), %rax
jae 0x45448
movq -0x70(%rbp), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x88(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x472a0
cmpl $0x0, %eax
je 0x45438
jmp 0x45448
jmp 0x4543a
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x45408
cmpq $0x0, -0x90(%rbp)
je 0x4545f
movq -0x30(%rbp), %rax
cmpq -0x90(%rbp), %rax
jne 0x4547a
movq -0x88(%rbp), %rax
movq 0x8(%rax), %rdx
leaq -0x70(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x48290
jmp 0x4547c
jmp 0x4549d
leaq 0x8899(%rip), %rdi      # 0x4dd1e
leaq 0x10029(%rip), %rsi     # 0x554b5
movl $0x2e4, %edx            # imm = 0x2E4
leaq 0x101fb(%rip), %rcx     # 0x55693
callq 0x6160
jmp 0x4549f
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x45383
jmp 0x454b2
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x4535d
movq $0x0, -0x48(%rbp)
movq $0x0, -0xa8(%rbp)
movq $0x0, -0x78(%rbp)
movq $0x0, -0xb8(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x90(%rbp), %rax
jae 0x455f3
movq $0x0, -0x60(%rbp)
movq $0x0, -0xa0(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x45592
movq -0x10(%rbp), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x58(%rbp)
movq -0x70(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x80(%rbp), %rax
movq (%rax), %rsi
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x10(%rbp), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rcx
callq 0x47340
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x45582
movq -0x58(%rbp), %rdx
leaq -0x60(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x48290
jmp 0x45584
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x4551d
cmpq $0x0, -0xa0(%rbp)
jbe 0x455e0
movq -0x60(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0x451d0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdx
leaq -0x48(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x48290
movq -0x70(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
leaq -0x78(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x48290
jmp 0x455e2
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x454f1
movq $0x0, -0x68(%rbp)
movq $0x0, -0xb0(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x456f0
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x58(%rbp)
movq $-0x1, -0x30(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jae 0x45686
movq -0x80(%rbp), %rax
movq (%rax), %rdi
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
callq 0x47220
cmpl $0x0, %eax
je 0x45676
movq -0x28(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x45678
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x4563c
cmpq $-0x1, -0x30(%rbp)
je 0x456c9
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdi
callq 0x2f210
cmpl $0x33, %eax
je 0x456c9
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdi
callq 0x2f210
cmpl $0x34, %eax
jne 0x456dd
movq -0x58(%rbp), %rdx
leaq -0x68(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x48290
jmp 0x456df
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x4560e
cmpq $0x0, -0xb0(%rbp)
je 0x45710
movq -0x68(%rbp), %rdi
movq -0xb0(%rbp), %rsi
callq 0x451d0
movq %rax, -0x50(%rbp)
jmp 0x45718
movq $0x0, -0x50(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq 0x38655(%rip), %rax     # 0x7dd88
jae 0x457c5
movq 0x38650(%rip), %rax     # 0x7dd90
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpb $0x0, 0x28(%rax)
jne 0x457b2
movq 0x3863b(%rip), %rax     # 0x7dd90
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x78(%rbp), %rdx
movq -0xb8(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0xa8(%rbp), %r9
movq -0x50(%rbp), %rax
movq %rax, (%rsp)
callq 0x474f0
cmpl $0x0, %eax
je 0x457b2
movq 0x385fc(%rip), %rax     # 0x7dd90
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x68(%rax)
jmp 0x457c5
jmp 0x457b4
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x45728
cmpq $0x0, -0x40(%rbp)
jne 0x45811
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xc8(%rbp)
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rdi
callq 0x2fd00
movq %rax, %rsi
movq -0xc8(%rbp), %rax
movq (%rax), %rdi
callq 0x46de0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x68(%rax)
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0xb8(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x78(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0xa8(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x48(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x50(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x50(%rax)
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2f210
movl %eax, %ecx
movl %ecx, -0xcc(%rbp)
subl $0x13, %eax
je 0x458f7
jmp 0x4587f
movl -0xcc(%rbp), %eax
subl $0x28, %eax
je 0x458f7
jmp 0x4588c
movl -0xcc(%rbp), %eax
subl $0x2a, %eax
je 0x458f7
jmp 0x45899
movl -0xcc(%rbp), %eax
subl $0x33, %eax
je 0x458f7
jmp 0x458a6
movl -0xcc(%rbp), %eax
subl $0x43, %eax
je 0x458c3
jmp 0x458b3
movl -0xcc(%rbp), %eax
addl $-0x44, %eax
subl $0x2, %eax
jb 0x458f7
jmp 0x45921
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x50(%rax), %rax
movq (%rax), %rdi
callq 0x30340
movq %rax, %rdi
callq 0x36a30
movq %rax, %rdi
callq 0x47620
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x45987
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x30340
movq %rax, %rdi
callq 0x36a30
movq %rax, %rdi
callq 0x47620
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x45987
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xe0(%rbp)
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x2f210
movl %eax, %eax
movl %eax, %ecx
leaq 0x36578(%rip), %rax     # 0x7bec0
movq (%rax,%rcx,8), %rax
movq %rax, -0xd8(%rbp)
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x30340
movq %rax, %rdi
callq 0x38a10
movq -0xe0(%rbp), %rdi
movq -0xd8(%rbp), %rdx
movq %rax, %rcx
leaq 0xfbd0(%rip), %rsi      # 0x55550
movb $0x0, %al
callq 0x1dfe0
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xf0, %rsp
popq %rbp
retq
nopl (%rax)