// File: /workspace/github_cpp_makefile_star2_O2/rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::attempt_emit_loop_header(spirv_cross::SPIRBlock&, spirv_cross::SPIRBlock::Method)
bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method method)
{
	SPIRBlock::ContinueBlockType continue_type = continue_block_type(get<SPIRBlock>(block.continue_block));

	if (method == SPIRBlock::MergeToSelectForLoop || method == SPIRBlock::MergeToSelectContinueForLoop)
	{
		uint32_t current_count = statement_count;
		// If we're trying to create a true for loop,
		// we need to make sure that all opcodes before branch statement do not actually emit any code.
		// We can then take the condition expression and create a for (; cond ; ) { body; } structure instead.
		emit_block_instructions(block);

		bool condition_is_temporary = forced_temporaries.find(block.condition) == end(forced_temporaries);

		// This can work! We only did trivial things which could be forwarded in block body!
		if (current_count == statement_count && condition_is_temporary)
		{
			switch (continue_type)
			{
			case SPIRBlock::ForLoop:
			{
				// This block may be a dominating block, so make sure we flush undeclared variables before building the for loop header.
				flush_undeclared_variables(block);

				// Important that we do this in this order because
				// emitting the continue block can invalidate the condition expression.
				auto initializer = emit_for_loop_initializers(block);
				auto condition = to_expression(block.condition);
				emit_block_hints(block);
				if (method != SPIRBlock::MergeToSelectContinueForLoop)
				{
					auto continue_block = emit_continue_block(block.continue_block);
					statement("for (", initializer, "; ", condition, "; ", continue_block, ")");
				}
				else
					statement("for (", initializer, "; ", condition, "; )");
				break;
			}

			case SPIRBlock::WhileLoop:
				// This block may be a dominating block, so make sure we flush undeclared variables before building the while loop header.
				flush_undeclared_variables(block);
				emit_while_loop_initializers(block);
				emit_block_hints(block);
				statement("while (", to_expression(block.condition), ")");
				break;

			default:
				SPIRV_CROSS_THROW("For/while loop detected, but need while/for loop semantics.");
			}

			begin_scope();
			return true;
		}
		else
		{
			block.disable_block_optimization = true;
			force_recompile = true;
			begin_scope(); // We'll see an end_scope() later.
			return false;
		}
	}
	else if (method == SPIRBlock::MergeToDirectForLoop)
	{
		auto &child = get<SPIRBlock>(block.next_block);

		// This block may be a dominating block, so make sure we flush undeclared variables before building the for loop header.
		flush_undeclared_variables(child);

		uint32_t current_count = statement_count;

		// If we're trying to create a true for loop,
		// we need to make sure that all opcodes before branch statement do not actually emit any code.
		// We can then take the condition expression and create a for (; cond ; ) { body; } structure instead.
		emit_block_instructions(child);

		bool condition_is_temporary = forced_temporaries.find(child.condition) == end(forced_temporaries);

		if (current_count == statement_count && condition_is_temporary)
		{
			propagate_loop_dominators(child);

			switch (continue_type)
			{
			case SPIRBlock::ForLoop:
			{
				// Important that we do this in this order because
				// emitting the continue block can invalidate the condition expression.
				auto initializer = emit_for_loop_initializers(block);
				auto condition = to_expression(child.condition);
				auto continue_block = emit_continue_block(block.continue_block);
				emit_block_hints(block);
				statement("for (", initializer, "; ", condition, "; ", continue_block, ")");
				break;
			}

			case SPIRBlock::WhileLoop:
				emit_while_loop_initializers(block);
				emit_block_hints(block);
				statement("while (", to_expression(child.condition), ")");
				break;

			default:
				SPIRV_CROSS_THROW("For/while loop detected, but need while/for loop semantics.");
			}

			begin_scope();
			branch(child.self, child.true_block);
			return true;
		}
		else
		{
			block.disable_block_optimization = true;
			force_recompile = true;
			begin_scope(); // We'll see an end_scope() later.
			return false;
		}
	}
	else
		return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
movl 0x20(%rsi), %esi
callq 0x6bf0
movq %rbx, %rdi
movq %rax, %rsi
callq 0x12510
movl %eax, %r12d
testl $0xfffffffd, %ebp       # imm = 0xFFFFFFFD
je 0x404dd
cmpl $0x1, %ebp
jne 0x405b0
movl 0x18(%r14), %esi
movq %rbx, %rdi
callq 0x6bf0
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0x4081e
movl 0x750(%rbx), %ebp
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3746c
leaq 0x228(%rbx), %rdi
leaq 0x28(%r15), %r13
movq %r13, %rsi
callq 0x1c722
testq %rax, %rax
jne 0x40599
cmpl 0x750(%rbx), %ebp
jne 0x40599
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3fc56
cmpl $0x2, %r12d
je 0x4060e
cmpl $0x1, %r12d
jne 0x4073e
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3ff12
movl (%r13), %edx
leaq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x2b9f0
movl 0x20(%r14), %edx
leaq 0x48(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x3fd5c
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
callq *0x158(%rax)
leaq 0x55559(%rip), %rax     # 0x959f5
leaq 0x55547(%rip), %rsi     # 0x959ea
leaq 0x55546(%rip), %rcx     # 0x959f0
leaq 0x8(%rsp), %rdx
leaq 0x28(%rsp), %r8
movq %rbx, %rdi
movq %rcx, %r9
pushq %rax
pushq %r12
callq 0x472d8
popq %rax
popq %rcx
leaq 0x48(%rsp), %rdi
callq 0x6548
leaq 0x28(%rsp), %rdi
callq 0x6548
jmp 0x40655
movl 0x750(%rbx), %r15d
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3746c
leaq 0x228(%rbx), %rdi
leaq 0x28(%r14), %rsi
callq 0x1c722
testq %rax, %rax
jne 0x40599
cmpl 0x750(%rbx), %r15d
jne 0x40599
cmpl $0x2, %r12d
je 0x405b7
cmpl $0x1, %r12d
jne 0x406f3
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4081e
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3ff12
movl 0x28(%r14), %edx
leaq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x2b9f0
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
callq *0x158(%rax)
cmpl $0x2, %ebp
jne 0x40679
leaq 0x55476(%rip), %rsi     # 0x959ea
leaq 0x55475(%rip), %rcx     # 0x959f0
leaq 0x55471(%rip), %r9      # 0x959f3
leaq 0x8(%rsp), %rdx
leaq 0x28(%rsp), %r8
movq %rbx, %rdi
callq 0x473f4
jmp 0x406c6
movb $0x1, %al
movb %al, 0xb0(%r14)
movb %al, 0x1d0(%rbx)
movq %rbx, %rdi
callq 0x22d28
xorl %eax, %eax
jmp 0x406e4
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4081e
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3fe8e
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
callq *0x158(%rax)
movl 0x28(%r14), %edx
leaq 0x8(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2b9f0
leaq 0x55400(%rip), %rsi     # 0x959f7
leaq 0x553f7(%rip), %rcx     # 0x959f5
movq %rbx, %rdi
movq %r14, %rdx
callq 0x474ea
jmp 0x406d0
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3fe8e
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
callq *0x158(%rax)
movl (%r13), %edx
leaq 0x8(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2b9f0
leaq 0x553b4(%rip), %rsi     # 0x959f7
leaq 0x553ab(%rip), %rcx     # 0x959f5
movq %rbx, %rdi
movq %r14, %rdx
callq 0x474ea
leaq 0x8(%rsp), %rdi
callq 0x6548
movq %rbx, %rdi
callq 0x22d28
movl 0x8(%r15), %esi
movl 0x2c(%r15), %edx
movq %rbx, %rdi
callq 0x3f8dc
jmp 0x406e2
movl 0x20(%r14), %edx
leaq 0x48(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3fd5c
leaq 0x55361(%rip), %rax     # 0x959f5
leaq 0x5534f(%rip), %rsi     # 0x959ea
leaq 0x5534e(%rip), %rcx     # 0x959f0
leaq 0x8(%rsp), %rdx
leaq 0x28(%rsp), %r8
movq %rbx, %rdi
movq %rcx, %r9
pushq %rax
pushq %r14
callq 0x472d8
popq %rax
popq %rcx
leaq 0x48(%rsp), %rdi
callq 0x6548
leaq 0x28(%rsp), %rdi
callq 0x6548
leaq 0x8(%rsp), %rdi
callq 0x6548
movq %rbx, %rdi
callq 0x22d28
movb $0x1, %al
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x6140
movq %rax, %r14
leaq 0x552fa(%rip), %rsi     # 0x959ff
leaq 0x8(%rsp), %rdi
leaq 0x28(%rsp), %rdx
callq 0x6100
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x6f6e
xorl %ebp, %ebp
leaq 0xa6693(%rip), %rsi     # 0xe6dc0
movq 0xa78ac(%rip), %rdx     # 0xe7fe0
movq %r14, %rdi
callq 0x6490
jmp 0x40787
pushq $0x10
popq %rdi
callq 0x6140
movq %rax, %r14
leaq 0x552af(%rip), %rsi     # 0x959ff
leaq 0x8(%rsp), %rdi
leaq 0x28(%rsp), %rdx
callq 0x6100
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x6f6e
xorl %ebp, %ebp
leaq 0xa6648(%rip), %rsi     # 0xe6dc0
movq 0xa7861(%rip), %rdx     # 0xe7fe0
movq %r14, %rdi
callq 0x6490
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x6548
testb %bpl, %bpl
je 0x40815
jmp 0x407c8
movq %rax, %rbx
jmp 0x407c8
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x6548
jmp 0x407e8
jmp 0x407e5
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x6548
testb %bpl, %bpl
jne 0x407c8
jmp 0x40815
movq %rax, %rbx
movq %r14, %rdi
callq 0x6200
jmp 0x40815
movq %rax, %rbx
jmp 0x40801
jmp 0x407db
jmp 0x407db
movq %rax, %rbx
jmp 0x4080b
movq %rax, %rbx
jmp 0x407f2
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x6548
jmp 0x4080b
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x6548
leaq 0x28(%rsp), %rdi
callq 0x6548
leaq 0x8(%rsp), %rdi
callq 0x6548
movq %rbx, %rdi
callq 0x64b0
nop