// File: /workspace/github_c_makefile_star2_O3/deplinenoise[P]tundra/src/Driver.cpp
// Function: t2::DriverBuild(t2::Driver*)
BuildResult::Enum DriverBuild(Driver* self)
{
  const DagData* dag = self->m_DagData;
  const int pass_count = dag->m_Passes.GetCount();

#if ENABLED(CHECKED_BUILD)
  // Do some paranoia checking of the node state to make sure pass indices are
  // set up correctly.
  {
    ProfilerScope prof_scope("Tundra DebugCheckPassIndices", 0);
    int i = 0;
    for (int pass = 0; pass < pass_count; ++pass)
    {
      for (int n = 0, node_count = self->m_PassNodeCount[pass]; n < node_count; ++n)
      {
        CHECK(self->m_Nodes[i].m_PassIndex == pass);
        ++i;
      }
    }
    CHECK(size_t(i) == self->m_Nodes.m_Size);
  }
#endif

  // Initialize build queue
  Mutex debug_signing_mutex;

  int max_expensive_count = self->m_DagData->m_MaxExpensiveCount;

  if (max_expensive_count < 0)
    max_expensive_count = self->m_Options.m_ThreadCount;
  else
    max_expensive_count = std::max(std::min(max_expensive_count, self->m_Options.m_ThreadCount), 1);

  Log(kDebug, "Max # expensive jobs: %d", max_expensive_count);

  BuildQueueConfig queue_config;
  queue_config.m_Flags                   = 0;
  queue_config.m_Heap                    = &self->m_Heap;
  queue_config.m_ThreadCount             = (int) self->m_Options.m_ThreadCount;
  queue_config.m_NodeData                = self->m_DagData->m_NodeData;
  queue_config.m_NodeState               = self->m_Nodes.m_Storage;
  queue_config.m_MaxNodes                = (int) self->m_Nodes.m_Size;
  queue_config.m_NodeRemappingTable      = self->m_NodeRemap.m_Storage;
  queue_config.m_ScanCache               = &self->m_ScanCache;
  queue_config.m_StatCache               = &self->m_StatCache;
  queue_config.m_DigestCache             = &self->m_DigestCache;
  queue_config.m_ShaDigestExtensionCount = dag->m_ShaExtensionHashes.GetCount();
  queue_config.m_ShaDigestExtensions     = dag->m_ShaExtensionHashes.GetArray();
  queue_config.m_MaxExpensiveCount       = max_expensive_count;

  if (self->m_Options.m_Verbose)
  {
    queue_config.m_Flags |= BuildQueueConfig::kFlagEchoAnnotations | BuildQueueConfig::kFlagEchoCommandLines;
  }
  if (!self->m_Options.m_Quiet)
  {
    queue_config.m_Flags |= BuildQueueConfig::kFlagEchoAnnotations;
  }
  if (self->m_Options.m_ContinueOnError)
  {
    queue_config.m_Flags |= BuildQueueConfig::kFlagContinueOnError;
  }

  if (self->m_Options.m_DebugSigning)
  {
    MutexInit(&debug_signing_mutex);
    queue_config.m_FileSigningLogMutex = &debug_signing_mutex;
    queue_config.m_FileSigningLog      = fopen("signing-debug.txt", "w");
  }
  else
  {
    queue_config.m_FileSigningLogMutex = nullptr;
    queue_config.m_FileSigningLog      = nullptr;
  }

#if ENABLED(CHECKED_BUILD)
  {
    ProfilerScope prof_scope("Tundra DebugCheckRemap", 0);
    // Paranoia - double check node remapping table
    for (size_t i = 0, count = self->m_Nodes.m_Size; i < count; ++i)
    {
      const NodeState* state = self->m_Nodes.m_Storage + i;
      const NodeData* src = state->m_MmapData;
      const int src_index = int(src - self->m_DagData->m_NodeData);
      int remapped_index = self->m_NodeRemap[src_index];
      CHECK(size_t(remapped_index) == i);
    }
  }
#endif


  BuildQueue build_queue;
  BuildQueueInit(&build_queue, &queue_config);

  int global_node_index = 0;

  BuildResult::Enum build_result = BuildResult::kOk;

  for (int pass = 0; BuildResult::kOk == build_result && pass < pass_count; ++pass)
  {
    const char *pass_name  = dag->m_Passes[pass].m_PassName;
    const int   pass_nodes = self->m_PassNodeCount[pass];

    Log(kInfo, "begin pass %s (nodes: %d - %d (%d))",
        pass_name, global_node_index, global_node_index + pass_nodes - 1, pass_nodes);

    build_result = BuildQueueBuildNodeRange(&build_queue, global_node_index, pass_nodes, pass);

    global_node_index += pass_nodes;

    Log(kInfo, "end pass %s", pass_name);
  }

  if (self->m_Options.m_DebugSigning)
  {
    fclose((FILE*)queue_config.m_FileSigningLog);
    MutexDestroy(&debug_signing_mutex);
  }

  // Shut down build queue
  BuildQueueDestroy(&build_queue);

  return build_result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1d8, %rsp            # imm = 0x1D8
movq %rdi, %r14
movq 0xa0(%rdi), %rax
movq %rax, 0x8(%rsp)
movl 0x68(%rax), %eax
testl %eax, %eax
js 0xa4a8
movl 0xc8(%r14), %ecx
cmpl %eax, %ecx
cmovll %ecx, %eax
cmpl $0x2, %eax
movl $0x1, %ebp
cmovgel %eax, %ebp
jmp 0xa4af
movl 0xc8(%r14), %ebp
movq 0x8(%rsp), %r15
movl 0x10(%r15), %eax
movq %rax, 0x10(%rsp)
leaq 0xc19c(%rip), %rsi      # 0x16660
xorl %ebx, %ebx
movl $0x8, %edi
movl %ebp, %edx
xorl %eax, %eax
callq 0x5d74
movl $0x0, 0x18(%rsp)
movq %r14, 0x20(%rsp)
movl 0xc8(%r14), %eax
movl %eax, 0x28(%rsp)
movq 0xa0(%r14), %rax
movslq 0xc(%rax), %rcx
testq %rcx, %rcx
leaq 0xc(%rcx,%rax), %rax
cmoveq %rcx, %rax
movq %rax, 0x30(%rsp)
movq 0x100(%r14), %rax
movq %rax, 0x38(%rsp)
movl 0x108(%r14), %eax
movl %eax, 0x40(%rsp)
movq 0xe8(%r14), %rax
movq %rax, 0x48(%rsp)
leaq 0x150(%r14), %rax
movq %rax, 0x50(%rsp)
leaq 0x1f0(%r14), %rax
movq %rax, 0x58(%rsp)
leaq 0x268(%r14), %rax
movq %rax, 0x60(%rsp)
movl 0x60(%r15), %eax
movl %eax, 0x68(%rsp)
movslq 0x64(%r15), %rax
testq %rax, %rax
leaq 0x64(%rax,%r15), %rcx
cmoveq %rax, %rcx
movq %rcx, 0x70(%rsp)
movl %ebp, 0x88(%rsp)
cmpb $0x1, 0xbd(%r14)
jne 0xa58a
movl $0x3, 0x18(%rsp)
movl $0x3, %ebx
cmpb $0x0, 0xc1(%r14)
jne 0xa59b
orl $0x2, %ebx
movl %ebx, 0x18(%rsp)
cmpb $0x1, 0xc6(%r14)
jne 0xa5ac
orl $0x4, %ebx
movl %ebx, 0x18(%rsp)
cmpb $0x1, 0xc5(%r14)
jne 0xa5f8
movq %r14, %rbx
leaq 0x90(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x34d0
testl %eax, %eax
jne 0xa71b
movq %r14, 0x80(%rsp)
leaq 0xc097(%rip), %rdi      # 0x16679
leaq 0xbf0d(%rip), %rsi      # 0x164f6
callq 0x33c0
movq %rax, 0x78(%rsp)
movq %rbx, %r14
jmp 0xa600
xorps %xmm0, %xmm0
movups %xmm0, 0x78(%rsp)
leaq 0xb8(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x4304
cmpl $0x0, 0x10(%rsp)
jle 0xa6cc
addq $0x14, 0x8(%rsp)
xorl %ebx, %ebx
xorl %r13d, %r13d
xorl %r15d, %r15d
movq 0x8(%rsp), %rcx
movslq (%rcx), %rax
leaq (%rax,%rcx), %r12
testq %rax, %rax
cmoveq %rax, %r12
movslq (%r12,%r13,4), %rax
addq %rbx, %r12
addq %rax, %r12
testq %rax, %rax
cmoveq %rax, %r12
movq %r14, %rbp
movl 0x340(%r14,%r13,4), %r14d
leal -0x1(%r14,%r15), %r8d
movl $0x4, %edi
leaq 0xc020(%rip), %rsi      # 0x1668b
movq %r12, %rdx
movl %r15d, %ecx
movl %r14d, %r9d
xorl %eax, %eax
callq 0x5d74
leaq 0xb8(%rsp), %rdi
movl %r15d, %esi
movl %r14d, %edx
movl %r13d, %ecx
callq 0x4726
movl $0x4, %edi
leaq 0xc012(%rip), %rsi      # 0x166af
movq %r12, %rdx
movl %eax, %r12d
xorl %eax, %eax
callq 0x5d74
testl %r12d, %r12d
jne 0xa6d1
addl %r15d, %r14d
incq %r13
addq $0x4, %rbx
movl %r14d, %r15d
cmpq 0x10(%rsp), %r13
movq %rbp, %r14
jb 0xa62b
jmp 0xa6d4
xorl %r12d, %r12d
jmp 0xa6d4
movq %rbp, %r14
cmpb $0x0, 0xc5(%r14)
je 0xa6f9
movq 0x78(%rsp), %rdi
callq 0x3340
leaq 0x90(%rsp), %rdi
callq 0x33b0
testl %eax, %eax
jne 0xa724
leaq 0xb8(%rsp), %rdi
callq 0x4563
movl %r12d, %eax
addq $0x1d8, %rsp            # imm = 0x1D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xb2ee(%rip), %rdi      # 0x15a10
jmp 0xa72b
leaq 0xb3a9(%rip), %rdi      # 0x15ad4
xorl %eax, %eax
callq 0x5b09