// File: /workspace/github_c_makefile_star2_O2/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 $0x1e8, %rsp            # imm = 0x1E8
movq %rdi, %r14
movq 0xa0(%rdi), %rax
movq %rax, 0x8(%rsp)
movl 0x68(%rax), %eax
testl %eax, %eax
js 0x97df
movl 0xc8(%r14), %ecx
cmpl %eax, %ecx
cmovll %ecx, %eax
cmpl $0x2, %eax
pushq $0x1
popq %rbp
cmovgel %eax, %ebp
jmp 0x97e6
movl 0xc8(%r14), %ebp
movq 0x8(%rsp), %r15
movslq 0x10(%r15), %rax
movq %rax, 0x20(%rsp)
leaq 0xae63(%rip), %rsi      # 0x1465e
xorl %ebx, %ebx
pushq $0x8
popq %rdi
movl %ebp, %edx
xorl %eax, %eax
callq 0x5981
andl $0x0, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movl 0xc8(%r14), %eax
movl %eax, 0x38(%rsp)
movq 0xa0(%r14), %rax
movslq 0xc(%rax), %rcx
testq %rcx, %rcx
leaq 0xc(%rcx,%rax), %rax
cmoveq %rcx, %rax
movq %rax, 0x40(%rsp)
movq 0x100(%r14), %rax
movq %rax, 0x48(%rsp)
movl 0x108(%r14), %eax
movl %eax, 0x50(%rsp)
movq 0xe8(%r14), %rax
movq %rax, 0x58(%rsp)
leaq 0x150(%r14), %rax
movq %rax, 0x60(%rsp)
leaq 0x1f0(%r14), %rax
movq %rax, 0x68(%rsp)
leaq 0x268(%r14), %rax
movq %rax, 0x70(%rsp)
movl 0x60(%r15), %eax
movl %eax, 0x78(%rsp)
movslq 0x64(%r15), %rax
testq %rax, %rax
leaq 0x64(%rax,%r15), %rcx
cmoveq %rax, %rcx
movq %rcx, 0x80(%rsp)
movl %ebp, 0x98(%rsp)
cmpb $0x1, 0xbd(%r14)
jne 0x98bd
movl $0x3, 0x28(%rsp)
pushq $0x3
popq %rbx
cmpb $0x0, 0xc1(%r14)
jne 0x98ce
orl $0x2, %ebx
movl %ebx, 0x28(%rsp)
cmpb $0x1, 0xc6(%r14)
jne 0x98df
orl $0x4, %ebx
movl %ebx, 0x28(%rsp)
cmpb $0x1, 0xc5(%r14)
movq %r14, 0x18(%rsp)
jne 0x991b
leaq 0xa0(%rsp), %r14
movq %r14, %rdi
callq 0x5404
movq %r14, 0x90(%rsp)
leaq 0xad6a(%rip), %rdi      # 0x14677
leaq 0xabe0(%rip), %rsi      # 0x144f4
callq 0x33c0
jmp 0x9926
andq $0x0, 0x90(%rsp)
xorl %eax, %eax
leaq 0x28(%rsp), %rsi
movq %rax, 0x60(%rsi)
leaq 0xc8(%rsp), %rdi
callq 0x40b8
addq $0x14, 0x8(%rsp)
xorl %ebx, %ebx
xorl %r13d, %r13d
xorl %r14d, %r14d
xorl %r15d, %r15d
pushq $0x4
popq %rbp
testl %r14d, %r14d
jne 0x99fa
cmpq 0x20(%rsp), %r13
jge 0x99fa
movq 0x8(%rsp), %rcx
movslq (%rcx), %rax
leaq (%rax,%rcx), %r12
testq %rax, %rax
cmoveq %rax, %r12
movslq (%r12,%rbx), %rax
addq %rbx, %r12
addq %rax, %r12
testq %rax, %rax
cmoveq %rax, %r12
movq 0x18(%rsp), %rax
movl 0x340(%rax,%rbx), %r14d
leal (%r14,%r15), %eax
movl %eax, 0x14(%rsp)
leal -0x1(%r14,%r15), %r8d
movl %ebp, %edi
leaq 0xacde(%rip), %rsi      # 0x14689
movq %r12, %rdx
movl %r15d, %ecx
movl %r14d, %r9d
xorl %eax, %eax
callq 0x5981
leaq 0xc8(%rsp), %rdi
movl %r15d, %esi
movl %r14d, %edx
movl %r13d, %ecx
callq 0x43e4
movl %eax, %r14d
movl %ebp, %edi
leaq 0xacd0(%rip), %rsi      # 0x146ad
movq %r12, %rdx
xorl %eax, %eax
callq 0x5981
incq %r13
addq $0x4, %rbx
movl 0x14(%rsp), %eax
movl %eax, %r15d
jmp 0x9950
movq 0x18(%rsp), %rax
cmpb $0x0, 0xc5(%rax)
je 0x9a22
movq 0x88(%rsp), %rdi
callq 0x3340
leaq 0xa0(%rsp), %rdi
callq 0x5502
leaq 0xc8(%rsp), %rdi
callq 0x4289
movl %r14d, %eax
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq