// File: /workspace/github_c_makefile_star2_O2/deplinenoise[P]tundra/src/Driver.cpp
// Function: t2::DriverPrepareNodes(t2::Driver*, char const**, int)
bool DriverPrepareNodes(Driver* self, const char** targets, int target_count)
{
  ProfilerScope prof_scope("Tundra PrepareNodes", 0);

  const DagData    *dag       = self->m_DagData;
  const NodeData   *src_nodes = dag->m_NodeData;
  const HashDigest *src_guids = dag->m_NodeGuids;
  MemAllocHeap     *heap      = &self->m_Heap;

  Buffer<int32_t> node_stack;
  BufferInitWithCapacity(&node_stack, heap, 1024);

  DriverSelectNodes(dag, targets, target_count, &node_stack, heap);

  const size_t node_word_count = (dag->m_NodeCount + 31) / 32;
  uint32_t* node_visited_bits = HeapAllocateArrayZeroed<uint32_t>(heap, node_word_count);

  int node_count = 0;

  Buffer<int32_t> node_indices;
  BufferInitWithCapacity(&node_indices, heap, 1024);

  while (node_stack.m_Size > 0)
  {
    int       dag_index = BufferPopOne(&node_stack);
    const int dag_word  = dag_index / 32;
    const int dag_bit   = 1 << (dag_index &31);

    if (0 == (node_visited_bits[dag_word] & dag_bit))
    {
      const NodeData* node = src_nodes + dag_index;
      CHECK(uint32_t(node->m_PassIndex) < uint32_t(dag->m_Passes.GetCount()));

      BufferAppendOne(&node_indices, &self->m_Heap, dag_index);

      node_visited_bits[dag_word] |= dag_bit;

      // Update counts
      ++node_count;
      self->m_PassNodeCount[node->m_PassIndex]++;

      // Stash node dependencies on the work queue to keep iterating
      BufferAppend(&node_stack, &self->m_Heap, node->m_Dependencies.GetArray(), node->m_Dependencies.GetCount());
    }
  }

  HeapFree(heap, node_visited_bits);
  node_visited_bits = nullptr;

  // Allocate space for nodes
  NodeState* out_nodes = BufferAllocZero(&self->m_Nodes, &self->m_Heap, node_count);

  // Initialize node state
  for (int i = 0; i < node_count; ++i)
  {
    const NodeData* src_node = src_nodes + node_indices[i];
    out_nodes[i].m_MmapData  = src_node;
    out_nodes[i].m_PassIndex = (uint16_t) src_node->m_PassIndex;
  }

  // Find frozen node state from previous build, if present.
  if (const StateData* state_data = self->m_StateData)
  {
    const NodeStateData *frozen_states    = state_data->m_NodeStates;
    const HashDigest    *state_guids      = state_data->m_NodeGuids;
    const int            state_guid_count = state_data->m_NodeCount;

    for (int i = 0; i < node_count; ++i)
    {
      const HashDigest* src_guid = src_guids + node_indices[i];

      if (const HashDigest* old_guid = BinarySearch(state_guids, state_guid_count, *src_guid))
      {
        int state_index = int(old_guid - state_guids);
        out_nodes[i].m_MmapState = frozen_states + state_index;
      }
    }
  }


  // Sort the node state array based on which pass the nodes are in.
  auto compare_node_passes = [](const NodeState& l, const NodeState& r) -> bool
  {
    return l.m_PassIndex < r.m_PassIndex;
  };

  std::sort(out_nodes, out_nodes + node_count, compare_node_passes);

  // Now that our local order is established (sorted for pass purposes),
  // initialize a remapping table from global (dag) index to local (state)
  // index. This is so we can map any DAG node reference onto any local state.
  int32_t* node_remap = BufferAllocFill(&self->m_NodeRemap, heap, dag->m_NodeCount, -1);

  CHECK(node_remap == self->m_NodeRemap.m_Storage);

  for (int local_index = 0; local_index < node_count; ++local_index)
  {
    const NodeData* global_node = out_nodes[local_index].m_MmapData;
    const int global_index = int(global_node - src_nodes);
    CHECK(node_remap[global_index] == -1);
    node_remap[global_index] = local_index;
  }

  Log(kDebug, "Node remap: %d src nodes, %d active nodes, using %d bytes of node state buffer space",
      dag->m_NodeCount, node_count, sizeof(NodeState) * node_count);

  BufferDestroy(&node_stack, &self->m_Heap);
  BufferDestroy(&node_indices, &self->m_Heap);

  return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movl %edx, %ebp
movq %rsi, %r15
movq %rdi, %rbx
andl $0x0, 0x1c(%rsp)
leaq 0xb57c(%rip), %rdi      # 0x145c7
xorl %esi, %esi
callq 0x551c
movq 0xa0(%rbx), %rcx
movslq 0xc(%rcx), %rax
testq %rax, %rax
leaq 0xc(%rax,%rcx), %rdx
cmoveq %rax, %rdx
movq %rdx, 0x38(%rsp)
movslq 0x8(%rcx), %rax
testq %rax, %rax
movq %rcx, 0x10(%rsp)
leaq 0x8(%rax,%rcx), %rcx
cmoveq %rax, %rcx
movq %rcx, 0x58(%rsp)
movl $0x1000, %esi           # imm = 0x1000
movq %rbx, %rdi
callq 0xd79a
movq %rax, 0x20(%rsp)
andq $0x0, 0x28(%rsp)
movq $0x400, 0x30(%rsp)      # imm = 0x400
xorps %xmm0, %xmm0
leaq 0x80(%rsp), %rdx
movaps %xmm0, (%rdx)
andq $0x0, 0x10(%rdx)
leaq 0x60(%rsp), %rcx
movaps %xmm0, (%rcx)
andq $0x0, 0x10(%rcx)
movq 0x10(%rsp), %r8
movl 0x18(%r8), %eax
leaq 0xa0(%rsp), %rdi
movl %eax, (%rdi)
movl 0x24(%r8), %eax
movl %eax, 0x4(%rdi)
movl 0x30(%r8), %eax
movl %eax, 0x8(%rdi)
movslq 0x20(%r8), %rax
testq %rax, %rax
leaq 0x20(%rax,%r8), %rsi
cmoveq %rax, %rsi
movq %rsi, 0x10(%rdi)
movslq 0x2c(%r8), %rax
testq %rax, %rax
leaq 0x2c(%rax,%r8), %rsi
cmoveq %rax, %rsi
movq %rsi, 0x18(%rdi)
movslq 0x38(%r8), %rax
testq %rax, %rax
leaq 0x38(%rax,%r8), %rsi
cmoveq %rax, %rsi
movq %rsi, 0x20(%rdi)
movl %ebp, 0x28(%rdi)
movq %r15, 0x30(%rdi)
movq 0x44(%r8), %rax
movq %rax, 0x38(%rdi)
movl 0x4c(%r8), %eax
movl %eax, 0x40(%rdi)
movq %rbx, %rsi
callq 0x104b0
movq %rbx, 0x8(%rsp)
movq 0x80(%rsp), %r13
imulq $0xc, 0x88(%rsp), %rbp
addq %r13, %rbp
movq 0x10(%rsp), %rax
addq $0x40, %rax
movq %rax, 0x40(%rsp)
leaq 0x20(%rsp), %r15
cmpq %rbp, %r13
je 0x9260
movq (%r13), %rax
movl 0x8(%r13), %ecx
movq %rax, %rdx
shrq $0x20, %rdx
movq 0x10(%rsp), %rdi
movslq 0x40(%rdi), %rsi
movq 0x40(%rsp), %r8
leaq (%rsi,%r8), %r12
testq %rsi, %rsi
cmoveq %rsi, %r12
movslq 0x3c(%rdi), %rdi
pushq $-0x10
popq %rsi
subq %r12, %rsi
pushq $-0x18
popq %r14
subq %r12, %r14
imulq $0x24, %rdi, %rdi
testq %rdi, %rdi
je 0x95c1
cmpl %eax, (%r12)
jne 0x91d3
cmpl %edx, 0x4(%r12)
jne 0x91d3
cmpl %ecx, 0x8(%r12)
je 0x91e5
addq $0x24, %r12
addq $-0x24, %rsi
addq $-0x24, %r14
addq $-0x24, %rdi
jmp 0x91b6
movq 0x68(%rsp), %r8
testq %r8, %r8
je 0x920e
movq 0x60(%rsp), %rcx
movq 0x10(%rsp), %rdi
movq %r15, %rsi
movq 0x8(%rsp), %rbx
movq %rbx, %rdx
movq %r12, %r9
callq 0xa613
jmp 0x9235
movslq 0x10(%r12), %rax
movq %rax, %rdx
subq %rsi, %rdx
testq %rax, %rax
cmoveq %rax, %rdx
movslq 0xc(%r12), %rcx
movq %r15, %rdi
movq 0x8(%rsp), %rbx
movq %rbx, %rsi
callq 0xc123
movslq 0x18(%r12), %rax
movq %rax, %rdx
subq %r14, %rdx
testq %rax, %rax
cmoveq %rax, %rdx
movslq 0x14(%r12), %rcx
movq %r15, %rdi
movq %rbx, %rsi
callq 0xc123
addq $0xc, %r13
jmp 0x9170
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
leaq (%rdi,%rax,4), %rsi
callq 0xc26c
movq 0x8(%rsp), %rbx
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
leaq (%rdi,%rax,4), %rsi
callq 0xc66c
subq 0x20(%rsp), %rax
sarq $0x2, %rax
movq %rax, 0x28(%rsp)
leaq 0xb677(%rip), %rsi      # 0x14917
pushq $0x8
popq %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x5981
leaq 0x60(%rsp), %rdi
movq %rbx, %rsi
callq 0xc214
leaq 0x80(%rsp), %rdi
movq %rbx, %rsi
callq 0xc238
movq 0x10(%rsp), %rax
movl 0x4(%rax), %eax
addl $0x1f, %eax
pushq $0x20
popq %rcx
cltd
idivl %ecx
movslq %eax, %rsi
movq %rbx, %rdi
callq 0x81b3
movq %rax, %r12
movl $0x1000, %esi           # imm = 0x1000
movq %rbx, %rdi
callq 0xd79a
leaq 0xa0(%rsp), %rcx
movq %rax, (%rcx)
andq $0x0, 0x8(%rcx)
movq $0x400, 0x10(%rcx)      # imm = 0x400
movq $-0x400, 0x48(%rsp)     # imm = 0xFC00
xorl %r15d, %r15d
pushq $0x1
popq %r13
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdi
decq %rdi
cmpq $-0x1, %rdi
je 0x93c0
movq %rdi, 0x28(%rsp)
movslq (%rsi,%rdi,4), %rbp
movl %ebp, %eax
cltd
pushq $0x20
popq %rcx
idivl %ecx
movl %r13d, %r14d
movl %ebp, %ecx
shll %cl, %r14d
movslq %eax, %rbx
movl (%r12,%rbx,4), %eax
decq %rdi
btl %ebp, %eax
jb 0x932a
leaq 0xa0(%rsp), %rdi
movq 0x8(%rsp), %rsi
movl %ebp, %edx
callq 0x7e97
imulq $0x48, %rbp, %rax
movq 0x38(%rsp), %r8
leaq (%r8,%rax), %rcx
orl %r14d, (%r12,%rbx,4)
movslq 0xc(%r8,%rax), %rdx
movq 0x8(%rsp), %rsi
incl 0x340(%rsi,%rdx,4)
incq %r15
movslq 0x14(%r8,%rax), %rdi
testq %rdi, %rdi
leaq 0x14(%rdi,%rcx), %rdx
cmoveq %rdi, %rdx
movslq 0x10(%r8,%rax), %rcx
addq $0x40, 0x48(%rsp)
leaq 0x20(%rsp), %rdi
callq 0xc123
jmp 0x931d
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0xd7a2
leaq 0x100(%rbx), %rdi
movl %r15d, %edx
movq %rbx, %rsi
movq %rdx, 0x50(%rsp)
callq 0xc14e
movq %rax, %r12
movq 0xa0(%rsp), %rax
leaq 0x2(%r12), %rcx
xorl %edx, %edx
movq 0x38(%rsp), %r8
cmpq %rdx, %r15
je 0x9425
movslq (%rax,%rdx,4), %rsi
imulq $0x48, %rsi, %rsi
leaq (%r8,%rsi), %rdi
movq %rdi, 0x6(%rcx)
movzwl 0xc(%r8,%rsi), %esi
movw %si, (%rcx)
incq %rdx
addq $0x40, %rcx
jmp 0x93fe
movq 0xa8(%rbx), %rax
testq %rax, %rax
je 0x94a7
movslq 0xc(%rax), %rcx
testq %rcx, %rcx
leaq 0xc(%rcx,%rax), %rdx
cmoveq %rcx, %rdx
movq %rdx, 0x40(%rsp)
movslq 0x8(%rax), %rcx
testq %rcx, %rcx
leaq 0x8(%rcx,%rax), %r13
cmoveq %rcx, %r13
movl 0x4(%rax), %ebp
leaq 0x10(%r12), %r14
xorl %ebx, %ebx
cmpq %rbx, %r15
je 0x94a7
movq 0xa0(%rsp), %rax
movslq (%rax,%rbx,4), %rdx
shlq $0x4, %rdx
addq 0x58(%rsp), %rdx
movq %r13, %rdi
movl %ebp, %esi
callq 0xc169
testq %rax, %rax
je 0x949e
subq %r13, %rax
shrq $0x4, %rax
cltq
imulq $0x24, %rax, %rax
addq 0x40(%rsp), %rax
movq %rax, (%r14)
incq %rbx
addq $0x40, %r14
jmp 0x9460
movq 0x50(%rsp), %rax
movq %rax, %r13
shlq $0x6, %r13
testl %r15d, %r15d
movq 0x8(%rsp), %rbx
movq 0x48(%rsp), %r14
je 0x9519
leaq (%r12,%r13), %rbp
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r12, %rdi
movq %rbp, %rsi
callq 0xadc3
cmpl $0x11, %r15d
jb 0x950e
leaq 0x400(%r12), %rbp
movq %r12, %rdi
movq %rbp, %rsi
callq 0xb2c9
testq %r14, %r14
je 0x9519
movq %rbp, %rdi
callq 0xb384
addq $0x40, %rbp
addq $-0x40, %r14
jmp 0x94f7
movq %r12, %rdi
movq %rbp, %rsi
callq 0xb2c9
leaq 0xe8(%rbx), %rdi
movq 0x10(%rsp), %rax
movslq 0x4(%rax), %rdx
pushq $-0x1
popq %rcx
movq %rbx, %rsi
callq 0xc1aa
movq 0x38(%rsp), %r9
movq %rax, %rcx
addq $0x8, %r12
xorl %esi, %esi
pushq $0x48
popq %rdi
movq %r15, %r8
subq $0x1, %r8
jb 0x9567
movq (%r12), %rax
subq %r9, %rax
cqto
idivq %rdi
cltq
movl %esi, (%rcx,%rax,4)
addq $0x40, %r12
incl %esi
jmp 0x9548
movq 0x10(%rsp), %rax
movl 0x4(%rax), %edx
leaq 0xb065(%rip), %rsi      # 0x145db
pushq $0x8
popq %rdi
movl %r15d, %ecx
movq %r13, %r8
xorl %eax, %eax
callq 0x5981
leaq 0x20(%rsp), %rdi
movq %rbx, %rsi
callq 0x7ea6
leaq 0xa0(%rsp), %rdi
movq %rbx, %rsi
callq 0x7ea6
leaq 0x1c(%rsp), %rdi
callq 0x5488
movb $0x1, %al
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xb32e(%rip), %rdi      # 0x148f6
xorl %eax, %eax
callq 0x56cd
jmp 0x95dd
jmp 0x95dd
jmp 0x95dd
jmp 0x95dd
jmp 0x95dd
jmp 0x95dd
jmp 0x95dd
movq %rax, %rbx
leaq 0x1c(%rsp), %rdi
callq 0x5488
movq %rbx, %rdi
callq 0x35e0