// File: /workspace/github_cpp_makefile_star2_O1/rossy[P]crossc/SPIRV-Cross/spirv_msl.cpp
// Function: spirv_cross::CompilerMSL::extract_global_variables_from_function(unsigned int, std::set<unsigned int, std::less<unsigned int>, std::allocator<unsigned int>>&, std::unordered_set<unsigned int, std::hash<unsigned int>, std::equal_to<unsigned int>, std::allocator<unsigned int>>&, std::unordered_set<unsigned int, std::hash<unsigned int>, std::equal_to<unsigned int>, std::allocator<unsigned int>>&)
void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::set<uint32_t> &added_arg_ids,
                                                         unordered_set<uint32_t> &global_var_ids,
                                                         unordered_set<uint32_t> &processed_func_ids)
{
	// Avoid processing a function more than once
	if (processed_func_ids.find(func_id) != processed_func_ids.end())
	{
		// Return function global variables
		added_arg_ids = function_global_vars[func_id];
		return;
	}

	processed_func_ids.insert(func_id);

	auto &func = get<SPIRFunction>(func_id);

	// Recursively establish global args added to functions on which we depend.
	for (auto block : func.blocks)
	{
		auto &b = get<SPIRBlock>(block);
		for (auto &i : b.ops)
		{
			auto ops = stream(i);
			auto op = static_cast<Op>(i.op);

			switch (op)
			{
			case OpLoad:
			case OpInBoundsAccessChain:
			case OpAccessChain:
			{
				uint32_t base_id = ops[2];
				if (global_var_ids.find(base_id) != global_var_ids.end())
					added_arg_ids.insert(base_id);

				auto &type = get<SPIRType>(ops[0]);
				if (type.basetype == SPIRType::Image && type.image.dim == DimSubpassData)
				{
					// Implicitly reads gl_FragCoord.
					assert(builtin_frag_coord_id != 0);
					added_arg_ids.insert(builtin_frag_coord_id);
				}

				if (msl_options.swizzle_texture_samples && has_sampled_images && is_sampled_image_type(type))
				{
					// Implicitly reads spvAuxBuffer.
					assert(aux_buffer_id != 0);
					added_arg_ids.insert(aux_buffer_id);
				}

				break;
			}

			case OpFunctionCall:
			{
				// First see if any of the function call args are globals
				for (uint32_t arg_idx = 3; arg_idx < i.length; arg_idx++)
				{
					uint32_t arg_id = ops[arg_idx];
					if (global_var_ids.find(arg_id) != global_var_ids.end())
						added_arg_ids.insert(arg_id);
				}

				// Then recurse into the function itself to extract globals used internally in the function
				uint32_t inner_func_id = ops[2];
				std::set<uint32_t> inner_func_args;
				extract_global_variables_from_function(inner_func_id, inner_func_args, global_var_ids,
				                                       processed_func_ids);
				added_arg_ids.insert(inner_func_args.begin(), inner_func_args.end());
				break;
			}

			case OpStore:
			{
				uint32_t base_id = ops[0];
				if (global_var_ids.find(base_id) != global_var_ids.end())
					added_arg_ids.insert(base_id);
				break;
			}

			default:
				break;
			}

			// TODO: Add all other operations which can affect memory.
			// We should consider a more unified system here to reduce boiler-plate.
			// This kind of analysis is done in several places ...
		}
	}

	function_global_vars[func_id] = added_arg_ids;

	// Add the global variables as arguments to the function
	if (func_id != ir.default_entry_point)
	{
		for (uint32_t arg_id : added_arg_ids)
		{
			auto &var = get<SPIRVariable>(arg_id);
			uint32_t type_id = var.basetype;
			auto *p_type = &get<SPIRType>(type_id);

			if (is_builtin_variable(var) && p_type->basetype == SPIRType::Struct)
			{
				// Get the non-pointer type
				type_id = get_non_pointer_type_id(type_id);
				p_type = &get<SPIRType>(type_id);

				uint32_t mbr_idx = 0;
				for (auto &mbr_type_id : p_type->member_types)
				{
					BuiltIn builtin;
					bool is_builtin = is_member_builtin(*p_type, mbr_idx, &builtin);
					if (is_builtin && has_active_builtin(builtin, var.storage))
					{
						// Add a arg variable with the same type and decorations as the member
						uint32_t next_ids = ir.increase_bound_by(2);
						uint32_t ptr_type_id = next_ids + 0;
						uint32_t var_id = next_ids + 1;

						// Make sure we have an actual pointer type,
						// so that we will get the appropriate address space when declaring these builtins.
						auto &ptr = set<SPIRType>(ptr_type_id, get<SPIRType>(mbr_type_id));
						ptr.self = mbr_type_id;
						ptr.storage = var.storage;
						ptr.pointer = true;

						func.add_parameter(mbr_type_id, var_id, true);
						set<SPIRVariable>(var_id, ptr_type_id, StorageClassFunction);
						ir.meta[var_id].decoration = ir.meta[type_id].members[mbr_idx];
					}
					mbr_idx++;
				}
			}
			else
			{
				uint32_t next_id = ir.increase_bound_by(1);
				func.add_parameter(type_id, next_id, true);
				set<SPIRVariable>(next_id, type_id, StorageClassFunction, 0, arg_id);

				// Ensure the existing variable has a valid name and the new variable has all the same meta info
				set_name(arg_id, ensure_valid_name(to_name(arg_id), "v"));
				ir.meta[next_id] = ir.meta[arg_id];
			}
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rcx, %r13
movq %rdx, %rbx
movq %rdi, %r14
movl %esi, 0xc(%rsp)
movl %esi, %eax
movq (%r8), %rdi
movq %r8, 0x20(%rsp)
movq 0x8(%r8), %r8
xorl %r10d, %r10d
xorl %edx, %edx
divq %r8
movq (%rdi,%rdx,8), %rax
testq %rax, %rax
je 0x8ee84
movq (%rax), %r9
movq %rax, %r10
cmpl %esi, 0x8(%r9)
je 0x8ee84
movq %rdx, %rcx
movq %r9, %r11
movq (%r9), %r9
testq %r9, %r9
je 0x8ee81
movl 0x8(%r9), %edi
movq %rdi, %rax
xorl %edx, %edx
divq %r8
movl $0x0, %r10d
cmpq %rcx, %rdx
jne 0x8ee84
movq %r11, %r10
cmpl %esi, %edi
jne 0x8ee56
jmp 0x8ee84
xorl %r10d, %r10d
testq %r10, %r10
je 0x8eeb3
cmpq $0x0, (%r10)
je 0x8eeb3
addq $0x788, %r14            # imm = 0x788
leaq 0xc(%rsp), %rsi
movq %r14, %rdi
callq 0xa8c84
movq %rbx, %rdi
movq %rax, %rsi
callq 0xa8056
jmp 0x8f71c
leaq 0x38(%rsp), %rdx
movq 0x20(%rsp), %rdi
movq %rdi, (%rdx)
leaq 0xc(%rsp), %r15
movq %r15, %rsi
callq 0x1fc02
movl (%r15), %esi
movq %r14, %rdi
callq 0xb9ca
movq 0x68(%rax), %rcx
movq %rax, 0x78(%rsp)
movq 0x70(%rax), %rax
movq %rax, 0x68(%rsp)
cmpq %rax, %rcx
movq %r14, 0x18(%rsp)
je 0x8f1f4
leaq 0x7c0(%r14), %rax
movq %rax, 0x10(%rsp)
leaq 0x7c8(%r14), %rax
movq %rax, 0x28(%rsp)
movq %rcx, 0x30(%rsp)
movl (%rcx), %esi
movq %r14, %rdi
callq 0x78fe
movq 0x38(%rax), %rbp
movq 0x40(%rax), %r12
cmpq %r12, %rbp
je 0x8f1e0
movq %r14, %rdi
movq %rbp, %rsi
callq 0x1b906
movq %rax, %r15
movzwl (%rbp), %eax
addl $-0x39, %eax
cmpl $0x9, %eax
ja 0x8f1d7
leaq 0x319b3(%rip), %rcx     # 0xc0908
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x8(%r15), %ecx
movl %ecx, 0x38(%rsp)
movq (%r13), %rdi
movq 0x8(%r13), %r8
movq %rcx, %rax
xorl %edx, %edx
divq %r8
movq %rdx, %rsi
movq (%rdi,%rdx,8), %rdx
movl $0x0, %eax
testq %rdx, %rdx
je 0x8f13b
movq (%rdx), %r9
movq %rdx, %rax
cmpl 0x8(%r9), %ecx
je 0x8f13b
movq %r9, %r10
movq (%r9), %r9
testq %r9, %r9
je 0x8f139
movl 0x8(%r9), %edi
movq %rdi, %rax
xorl %edx, %edx
divq %r8
movl $0x0, %eax
cmpq %rsi, %rdx
jne 0x8f13b
movq %r10, %rax
cmpl %edi, %ecx
jne 0x8ef9b
jmp 0x8f13b
movl (%r15), %ecx
movl %ecx, 0x38(%rsp)
movq (%r13), %rdi
movq 0x8(%r13), %r8
movq %rcx, %rax
xorl %edx, %edx
divq %r8
movq %rdx, %rsi
movq (%rdi,%rdx,8), %rdx
movl $0x0, %eax
testq %rdx, %rdx
je 0x8f1bf
movq (%rdx), %r9
movq %rdx, %rax
cmpl 0x8(%r9), %ecx
je 0x8f1bf
movq %r9, %r10
movq (%r9), %r9
testq %r9, %r9
je 0x8f1bd
movl 0x8(%r9), %edi
movq %rdi, %rax
xorl %edx, %edx
divq %r8
movl $0x0, %eax
cmpq %rsi, %rdx
jne 0x8f1bf
movq %r10, %rax
cmpl %edi, %ecx
jne 0x8f00c
jmp 0x8f1bf
cmpl $0x4, 0x8(%rbp)
jb 0x8f0d9
movl $0x3, %r14d
movl (%r15,%r14,4), %ecx
movl %ecx, 0x38(%rsp)
movq (%r13), %rdi
movq 0x8(%r13), %r8
movq %rcx, %rax
xorl %edx, %edx
divq %r8
movq %rdx, %rsi
movq (%rdi,%rdx,8), %rdx
movl $0x0, %eax
testq %rdx, %rdx
je 0x8f0b2
movq (%rdx), %r9
movq %rdx, %rax
cmpl 0x8(%r9), %ecx
je 0x8f0b2
movq %r9, %r10
movq (%r9), %r9
testq %r9, %r9
je 0x8f0b0
movl 0x8(%r9), %edi
movq %rdi, %rax
xorl %edx, %edx
divq %r8
movl $0x0, %eax
cmpq %rsi, %rdx
jne 0x8f0b2
movq %r10, %rax
cmpl %edi, %ecx
jne 0x8f086
jmp 0x8f0b2
xorl %eax, %eax
testq %rax, %rax
je 0x8f0ca
cmpq $0x0, (%rax)
je 0x8f0ca
movq %rbx, %rdi
leaq 0x38(%rsp), %rsi
callq 0xa8f9c
incq %r14
movl 0x8(%rbp), %eax
cmpq %rax, %r14
jb 0x8f051
movl 0x8(%r15), %esi
movl $0x0, 0x40(%rsp)
xorl %eax, %eax
movq %rax, 0x48(%rsp)
leaq 0x40(%rsp), %r15
movq %r15, 0x50(%rsp)
movq %r15, 0x58(%rsp)
movq %rax, 0x60(%rsp)
movq 0x18(%rsp), %r14
movq %r14, %rdi
leaq 0x38(%rsp), %rdx
movq %r13, %rcx
movq 0x20(%rsp), %r8
callq 0x8ee0a
movq 0x50(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
callq 0xa90ac
leaq 0x38(%rsp), %rdi
callq 0xa8006
jmp 0x8f1d7
xorl %eax, %eax
testq %rax, %rax
je 0x8f153
cmpq $0x0, (%rax)
je 0x8f153
movq %rbx, %rdi
leaq 0x38(%rsp), %rsi
callq 0xa8f9c
movl (%r15), %esi
movq %r14, %rdi
callq 0xa426
movq %rax, %r15
cmpl $0xd, 0xc(%rax)
jne 0x8f187
cmpl $0x6, 0x84(%r15)
jne 0x8f187
movq 0x10(%rsp), %rsi
cmpl $0x0, (%rsi)
je 0x8f72e
movq %rbx, %rdi
callq 0xa8f9c
cmpb $0x1, 0x7df(%r14)
jne 0x8f1d7
cmpb $0x1, 0x934(%r14)
jne 0x8f1d7
movq %r14, %rdi
movq %r15, %rsi
callq 0x14caa
testb %al, %al
je 0x8f1d7
movq 0x28(%rsp), %rsi
cmpl $0x0, (%rsi)
je 0x8f74d
movq %rbx, %rdi
jmp 0x8f1d2
xorl %eax, %eax
testq %rax, %rax
je 0x8f1d7
cmpq $0x0, (%rax)
je 0x8f1d7
movq %rbx, %rdi
leaq 0x38(%rsp), %rsi
callq 0xa8f9c
addq $0xc, %rbp
jmp 0x8ef27
movq 0x30(%rsp), %rcx
addq $0x4, %rcx
cmpq 0x68(%rsp), %rcx
jne 0x8ef10
leaq 0x788(%r14), %rdi
leaq 0xc(%rsp), %r15
movq %r15, %rsi
callq 0xa8c84
movq %rax, %rdi
movq %rbx, %rsi
callq 0xa8056
movl (%r15), %eax
cmpl 0x108(%r14), %eax
je 0x8f71c
movq 0x18(%rbx), %rcx
addq $0x8, %rbx
movq %rbx, 0xa0(%rsp)
cmpq %rbx, %rcx
je 0x8f71c
leaq 0x8(%r14), %rax
movq %rax, 0x28(%rsp)
leaq 0x38(%rsp), %rbx
leaq 0xb8(%rsp), %r13
leaq 0x80(%rsp), %rbp
movq %rcx, 0xa8(%rsp)
movl 0x20(%rcx), %esi
movl %esi, 0x8(%rsp)
movq %r14, %rdi
callq 0xb40a
movq %rax, %r12
movl 0xc(%rax), %esi
movl %esi, (%rsp)
movq %r14, %rdi
callq 0xa426
movq %rax, %r15
movq %r14, %rdi
movq %r12, 0x30(%rsp)
movq %r12, %rsi
callq 0x133a2
testb %al, %al
je 0x8f496
cmpl $0xc, 0xc(%r15)
jne 0x8f496
movl (%rsp), %esi
movq %r14, %rdi
callq 0x14bf8
movl %eax, (%rsp)
movq %r14, %rdi
movl %eax, %esi
callq 0xa426
movq 0x68(%rax), %r14
movq 0x70(%rax), %r12
cmpq %r12, %r14
movq 0x30(%rsp), %r13
je 0x8f6e9
movq %rax, %r15
xorl %ebp, %ebp
movq %rax, 0x68(%rsp)
movq %r12, 0xb0(%rsp)
movq 0x18(%rsp), %rdi
movq %r15, %rsi
movl %ebp, %edx
movq %rbx, %rcx
callq 0x13472
testb %al, %al
je 0x8f482
movl 0x38(%rsp), %esi
movl 0x10(%r13), %edx
movq 0x18(%rsp), %rdi
callq 0x1a80e
testb %al, %al
je 0x8f482
movq 0x28(%rsp), %rdi
movl $0x2, %esi
callq 0x2561c
movl %eax, %r15d
movl %eax, 0x4(%rsp)
leal 0x1(%r15), %r12d
movl (%r14), %esi
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
callq 0xa426
movq %rbx, %rdi
movl %r15d, %esi
movq %rax, %rdx
callq 0x7cf58
movl (%r14), %ecx
movl %ecx, 0x8(%rax)
movl 0x10(%r13), %ecx
movl %ecx, 0x64(%rax)
movb $0x1, 0x60(%rax)
movl (%r14), %esi
movq 0x78(%rsp), %rdi
movl %r12d, %edx
movl $0x1, %ecx
callq 0xa4470
movl $0x7, 0x74(%rsp)
movq %rbx, %rdi
movl %r12d, %esi
leaq 0x4(%rsp), %rdx
leaq 0x74(%rsp), %rcx
callq 0x7cf9a
movl (%rsp), %eax
movq 0x38(%rbx), %rbx
imulq $0x148, %rax, %rax      # imm = 0x148
movl %ebp, %ecx
movq 0xd0(%rbx,%rax), %rax
movq %rax, 0x20(%rsp)
imulq $0xd0, %rcx, %rcx
movq %rcx, 0x10(%rsp)
leaq (%rax,%rcx), %r15
imulq $0x148, %r12, %r13      # imm = 0x148
leaq (%rbx,%r13), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x6170
leaq (%rbx,%r13), %rdi
addq $0x20, %rdi
movq 0x10(%rsp), %rax
movq 0x20(%rsp), %rcx
leaq (%rcx,%rax), %rsi
addq $0x20, %rsi
callq 0x6170
addq %rbx, %r13
addq $0x40, %r13
movq 0x10(%rsp), %rax
movq 0x20(%rsp), %rcx
leaq (%rcx,%rax), %rbx
addq $0x40, %rbx
movq %r13, %rdi
movq %rbx, %rsi
callq 0x6170
movq 0x20(%rbx), %rax
movq %rax, 0x20(%r13)
cmpq %r12, %r15
je 0x8f438
leaq 0x68(%r12), %rdi
leaq 0x68(%r15), %rsi
callq 0x1dcd0
movups 0xa0(%r15), %xmm0
movups 0xb0(%r15), %xmm1
movups 0xbd(%r15), %xmm2
movups %xmm2, 0xbd(%r12)
movups %xmm1, 0xb0(%r12)
movups %xmm0, 0xa0(%r12)
leaq 0x38(%rsp), %rbx
movq 0x30(%rsp), %r13
movq 0x68(%rsp), %r15
movq 0xb0(%rsp), %r12
incl %ebp
addq $0x4, %r14
cmpq %r12, %r14
jne 0x8f2e8
jmp 0x8f6e9
movq 0x28(%rsp), %rdi
movl $0x1, %esi
callq 0x2561c
movl %eax, %r12d
movl (%rsp), %esi
movq 0x78(%rsp), %rdi
movl %eax, %edx
movl $0x1, %ecx
callq 0xa4470
movl $0x7, 0x38(%rsp)
movl $0x0, 0x4(%rsp)
movq %r14, %rdi
movl %r12d, %esi
movq %rsp, %rdx
movq %rbx, %rcx
leaq 0x4(%rsp), %r8
leaq 0x8(%rsp), %r9
callq 0xa44bc
movl 0x8(%rsp), %r15d
movq (%r14), %rax
movq %r13, %rdi
movq %r14, %rsi
movl %r15d, %edx
movl $0x1, %ecx
callq *0x38(%rax)
leaq 0x90(%rsp), %rax
movq %rax, 0x80(%rsp)
movq %rbp, %rdi
leaq 0x31fe2(%rip), %rsi     # 0xc14fc
leaq 0x31fdc(%rip), %rdx     # 0xc14fd
callq 0x7c64
movq %rbx, %rdi
movq %r13, %rdx
movq %rbp, %rcx
callq 0x8f7f6
movq %r14, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x14bd2
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x8f55e
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x6260
movq 0x80(%rsp), %rdi
leaq 0x90(%rsp), %rax
cmpq %rax, %rdi
je 0x8f583
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x6260
movl %r12d, %r14d
movq 0xb8(%rsp), %rdi
leaq 0xc8(%rsp), %rax
cmpq %rax, %rdi
je 0x8f5ab
movq 0xc8(%rsp), %rsi
incq %rsi
callq 0x6260
movl 0x8(%rsp), %ecx
movq %rcx, 0x10(%rsp)
movq 0x18(%rsp), %rax
movq 0x38(%rax), %r12
imulq $0x148, %rcx, %rbp      # imm = 0x148
leaq (%r12,%rbp), %r15
movl %r14d, %eax
imulq $0x148, %rax, %rbx      # imm = 0x148
leaq (%r12,%rbx), %r13
movq %r13, %rdi
movq %r15, %rsi
callq 0x6170
leaq (%r12,%rbx), %rdi
addq $0x20, %rdi
leaq (%r12,%rbp), %rsi
addq $0x20, %rsi
callq 0x6170
addq %r12, %rbx
addq $0x40, %rbx
addq %rbp, %r12
addq $0x40, %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6170
movq 0x20(%r12), %rax
movq %rax, 0x20(%rbx)
cmpl %r14d, 0x10(%rsp)
jne 0x8f663
movups 0xa0(%r15), %xmm0
movups 0xb0(%r15), %xmm1
movups 0xbd(%r15), %xmm2
movups %xmm2, 0xbd(%r13)
movups %xmm1, 0xb0(%r13)
movups %xmm0, 0xa0(%r13)
movl $0xd0, %eax
leaq (%rax,%r13), %rdi
leaq (%r15,%rax), %rsi
callq 0x1dbfa
jmp 0x8f6c4
leaq 0x68(%r13), %rdi
leaq 0x68(%r15), %rsi
callq 0x1dcd0
movups 0xa0(%r15), %xmm0
movups 0xb0(%r15), %xmm1
movups 0xbd(%r15), %xmm2
movups %xmm2, 0xbd(%r13)
movups %xmm1, 0xb0(%r13)
movups %xmm0, 0xa0(%r13)
movl $0xd0, %eax
leaq (%rax,%r13), %rdi
leaq (%r15,%rax), %rsi
callq 0x1dbfa
movl $0xe8, %eax
leaq (%rax,%r13), %rdi
leaq (%r15,%rax), %rsi
callq 0x1e734
leaq 0x38(%rsp), %rbx
movl $0x120, %eax            # imm = 0x120
leaq (%rax,%r13), %rdi
leaq (%r15,%rax), %rsi
callq 0x6170
movq 0x140(%r15), %rax
movq %rax, 0x140(%r13)
movq 0xa8(%rsp), %rdi
callq 0x62e0
movq %rax, %rcx
cmpq 0xa0(%rsp), %rax
movq 0x18(%rsp), %r14
leaq 0xb8(%rsp), %r13
leaq 0x80(%rsp), %rbp
jne 0x8f25a
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x31ce3(%rip), %rdi     # 0xc1418
leaq 0x31cf7(%rip), %rsi     # 0xc1433
leaq 0x31d0a(%rip), %rcx     # 0xc144d
movl $0x276, %edx            # imm = 0x276
callq 0x61b0
leaq 0x31d95(%rip), %rdi     # 0xc14e9
leaq 0x31cd8(%rip), %rsi     # 0xc1433
leaq 0x31ceb(%rip), %rcx     # 0xc144d
movl $0x27d, %edx            # imm = 0x27D
callq 0x61b0
movq %rax, %rbx
jmp 0x8f790
movq %rax, %rbx
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x8f790
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x6260
movq 0x80(%rsp), %rdi
leaq 0x90(%rsp), %rax
cmpq %rax, %rdi
je 0x8f7ba
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0x8f7ba
movq %rax, %rbx
movq 0xb8(%rsp), %rdi
leaq 0xc8(%rsp), %rax
cmpq %rax, %rdi
je 0x8f7ee
movq 0xc8(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0x8f7ee
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0xa8006
movq %rbx, %rdi
callq 0x64a0