// File: rossy[P]crossc/SPIRV-Cross/spirv_cfg.cpp
// Function: spirv_cross::CFG::post_order_visit(unsigned int)
bool CFG::post_order_visit(uint32_t block_id)
{
	// If we have already branched to this block (back edge), stop recursion.
	// If our branches are back-edges, we do not record them.
	// We have to record crossing edges however.
	if (visit_order[block_id] >= 0)
		return !is_back_edge(block_id);

	// Block back-edges from recursively revisiting ourselves.
	visit_order[block_id] = 0;

	// First visit our branch targets.
	auto &block = compiler.get<SPIRBlock>(block_id);
	switch (block.terminator)
	{
	case SPIRBlock::Direct:
		if (post_order_visit(block.next_block))
			add_branch(block_id, block.next_block);
		break;

	case SPIRBlock::Select:
		if (post_order_visit(block.true_block))
			add_branch(block_id, block.true_block);
		if (post_order_visit(block.false_block))
			add_branch(block_id, block.false_block);
		break;

	case SPIRBlock::MultiSelect:
		for (auto &target : block.cases)
		{
			if (post_order_visit(target.block))
				add_branch(block_id, target.block);
		}
		if (block.default_block && post_order_visit(block.default_block))
			add_branch(block_id, block.default_block);
		break;

	default:
		break;
	}

	// If this is a loop header, add an implied branch to the merge target.
	// This is needed to avoid annoying cases with do { ... } while(false) loops often generated by inliners.
	// To the CFG, this is linear control flow, but we risk picking the do/while scope as our dominating block.
	// This makes sure that if we are accessing a variable outside the do/while, we choose the loop header as dominator.
	if (block.merge == SPIRBlock::MergeLoop)
		add_branch(block_id, block.merge_block);

	// Then visit ourselves. Start counting at one, to let 0 be a magic value for testing back vs. crossing edges.
	visit_order[block_id] = ++visit_count;
	post_order.push_back(block_id);
	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x48(%rbp)
addq $0x58, %rdi
movl -0x14(%rbp), %eax
movl %eax, %esi
callq 0x87b0
cmpl $0x0, (%rax)
jl 0x7ce2
movq -0x48(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x7c70
xorb $-0x1, %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x7ed1
movq -0x48(%rbp), %rdi
addq $0x58, %rdi
movl -0x14(%rbp), %eax
movl %eax, %esi
callq 0x87b0
movq %rax, %rcx
movq -0x48(%rbp), %rax
movl $0x0, (%rcx)
movq (%rax), %rdi
movl -0x14(%rbp), %esi
callq 0x87d0
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x4c(%rbp)
subl $0x1, %eax
je 0x7d3c
jmp 0x7d21
movl -0x4c(%rbp), %eax
subl $0x2, %eax
je 0x7d6a
jmp 0x7d2b
movl -0x4c(%rbp), %eax
subl $0x3, %eax
je 0x7dc1
jmp 0x7e74
movq -0x48(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x18(%rax), %esi
callq 0x7ca0
testb $0x1, %al
jne 0x7d52
jmp 0x7d65
movq -0x48(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rax
movl 0x18(%rax), %edx
callq 0x7ee0
jmp 0x7e76
movq -0x48(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x2c(%rax), %esi
callq 0x7ca0
testb $0x1, %al
jne 0x7d80
jmp 0x7d93
movq -0x48(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x7ee0
movq -0x48(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x30(%rax), %esi
callq 0x7ca0
testb $0x1, %al
jne 0x7da9
jmp 0x7dbc
movq -0x48(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rax
movl 0x30(%rax), %edx
callq 0x7ee0
jmp 0x7e76
movq -0x20(%rbp), %rax
addq $0x98, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x8810
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rdi
callq 0x8840
movq %rax, -0x38(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x8870
testb $0x1, %al
jne 0x7dfc
jmp 0x7e3f
leaq -0x30(%rbp), %rdi
callq 0x88b0
movq -0x48(%rbp), %rdi
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl 0x4(%rax), %esi
callq 0x7ca0
testb $0x1, %al
jne 0x7e1f
jmp 0x7e32
movq -0x48(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x40(%rbp), %rax
movl 0x4(%rax), %edx
callq 0x7ee0
jmp 0x7e34
leaq -0x30(%rbp), %rdi
callq 0x88d0
jmp 0x7de9
movq -0x20(%rbp), %rax
cmpl $0x0, 0x34(%rax)
je 0x7e72
movq -0x48(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x34(%rax), %esi
callq 0x7ca0
testb $0x1, %al
jne 0x7e5f
jmp 0x7e72
movq -0x48(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rax
movl 0x34(%rax), %edx
callq 0x7ee0
jmp 0x7e76
jmp 0x7e76
movq -0x20(%rbp), %rax
cmpl $0x1, 0x10(%rax)
jne 0x7e93
movq -0x48(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rax
movl 0x1c(%rax), %edx
callq 0x7ee0
movq -0x48(%rbp), %rdi
movl 0x88(%rdi), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
movl %eax, 0x88(%rdi)
addq $0x58, %rdi
movl -0x14(%rbp), %eax
movl %eax, %esi
callq 0x87b0
movl -0x50(%rbp), %ecx
movq -0x48(%rbp), %rdi
movl %ecx, (%rax)
addq $0x70, %rdi
leaq -0x14(%rbp), %rsi
callq 0x88f0
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)