// File: /workspace/github_c_makefile_star2_O3/deplinenoise[P]tundra/src/Driver.cpp
// Function: t2::DriverRemoveStaleOutputs(t2::Driver*)
void DriverRemoveStaleOutputs(Driver* self)
{
  TimingScope timing_scope(nullptr, &g_Stats.m_StaleCheckTimeCycles);
  ProfilerScope prof_scope("Tundra RemoveStaleOutputs", 0);

  const DagData* dag = self->m_DagData;
  const StateData* state = self->m_StateData;
  MemAllocLinear* scratch = &self->m_Allocator;

  MemAllocLinearScope scratch_scope(scratch);

  if (!state)
  {
    Log(kDebug, "unable to clean up stale output files - no previous build state");
    return;
  }

  HashSet<kFlagPathStrings> file_table;
  HashSetInit(&file_table, &self->m_Heap);

  // Insert all current regular and aux output files into the hash table.
  auto add_file = [&file_table](const FrozenFileAndHash& p) -> void
  {
    const uint32_t hash = p.m_FilenameHash;

    if (!HashSetLookup(&file_table, hash, p.m_Filename))
    {
      HashSetInsert(&file_table, hash, p.m_Filename);
    }
  };

  for (int i = 0, node_count = dag->m_NodeCount; i < node_count; ++i)
  {
    const NodeData* node = dag->m_NodeData + i;

    for (const FrozenFileAndHash& p : node->m_OutputFiles)
    {
      add_file(p);
    }

    for (const FrozenFileAndHash& p : node->m_AuxOutputFiles)
    {
      add_file(p);
    }
  }

  HashSet<kFlagPathStrings> nuke_table;
  HashSetInit(&nuke_table, &self->m_Heap);

  // Check all output files in the state if they're still around.
  // Otherwise schedule them (and all their parent dirs) for nuking.
  // We will rely on the fact that we can't rmdir() non-empty directories.
  auto check_file = [&file_table, &nuke_table, scratch](const char* path)
  {
    uint32_t path_hash = Djb2HashPath(path);

    if (!HashSetLookup(&file_table, path_hash, path))
    {
      if (!HashSetLookup(&nuke_table, path_hash, path))
      {
        HashSetInsert(&nuke_table, path_hash, path);
      }

      PathBuffer buffer;
      PathInit(&buffer, path);

      while (PathStripLast(&buffer))
      {
        if (buffer.m_SegCount == 0)
          break;

        char dir[kMaxPathLength];
        PathFormat(dir, &buffer);
        uint32_t dir_hash = Djb2HashPath(dir);

        if (!HashSetLookup(&nuke_table, dir_hash, dir))
        {
          HashSetInsert(&nuke_table, dir_hash, StrDup(scratch, dir));
        }
      }
    }
  };

  for (int i = 0, state_count = state->m_NodeCount; i < state_count; ++i)
  {
    const NodeStateData* node = state->m_NodeStates + i;

    for (const char* path : node->m_OutputFiles)
    {
      check_file(path);
    }

    for (const char* path : node->m_AuxOutputFiles)
    {
      check_file(path);
    }
  }

  // Create list of files and dirs, sort descending by path length. This sorts
  // files and subdirectories before their parent directories.
  const char** paths = LinearAllocateArray<const char*>(scratch, nuke_table.m_RecordCount);
  HashSetWalk(&nuke_table, [paths](uint32_t index, uint32_t hash, const char* str) {
    paths[index] = str;
  });

  std::sort(paths, paths + nuke_table.m_RecordCount, [](const char* l, const char* r) {
    return strlen(r) < strlen(l);
  });

  for (uint32_t i = 0, nuke_count = nuke_table.m_RecordCount; i < nuke_count; ++i)
  {
    Log(kDebug, "cleaning up %s", paths[i]);
    RemoveFileOrDir(paths[i]);
  }

  HashSetDestroy(&nuke_table);
  HashSetDestroy(&file_table);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rdi, %r13
movq $0x0, 0x88(%rsp)
leaq 0x12766(%rip), %rax     # 0x1d620
movq %rax, 0x90(%rsp)
callq 0x5f2a
movq %rax, 0x98(%rsp)
movl $0x0, 0x14(%rsp)
leaq 0x127a2(%rip), %rax     # 0x1d680
cmpb $0x1, (%rax)
jne 0xaef1
leaq 0xb7e2(%rip), %rdi      # 0x166cc
xorl %esi, %esi
callq 0xf4a3
movq 0x20(%r13), %rbp
movq 0xa8(%r13), %rax
testq %rax, %rax
je 0xb18d
movq %rax, 0x20(%rsp)
movq %rbp, (%rsp)
movq 0xa0(%r13), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x6c(%rsp)
movaps %xmm0, 0x60(%rsp)
movq %r13, 0x8(%rsp)
movq %r13, 0x80(%rsp)
movq %rax, 0x18(%rsp)
movslq 0x4(%rax), %rax
movq %rax, 0x58(%rsp)
testq %rax, %rax
jle 0xb05b
addq $0xc, 0x18(%rsp)
xorl %edx, %edx
leaq 0x60(%rsp), %r14
movq 0x18(%rsp), %rcx
movslq (%rcx), %rax
addq %rax, %rcx
testq %rax, %rax
cmoveq %rax, %rcx
movq %rdx, 0x28(%rsp)
leaq (%rdx,%rdx,8), %rax
leaq (%rcx,%rax,8), %r12
movslq 0x2c(%rcx,%rax,8), %rdx
testq %rdx, %rdx
leaq 0x2c(%rdx,%r12), %r13
cmoveq %rdx, %r13
movslq 0x28(%rcx,%rax,8), %r15
testq %r15, %r15
je 0xafdd
shlq $0x3, %r15
movq %r13, %rbx
movl 0x4(%r13), %ebp
movslq (%r13), %rax
leaq (%rbx,%rax), %rdx
testq %rax, %rax
cmoveq %rax, %rdx
movq %r14, %rdi
movl %ebp, %esi
callq 0x890c
cmpl $-0x1, %eax
jne 0xafcf
movslq (%r13), %rax
leaq (%rbx,%rax), %rdx
testq %rax, %rax
cmoveq %rax, %rdx
movq %r14, %rdi
movl %ebp, %esi
callq 0xd609
addq $0x8, %r13
addq $0x8, %rbx
addq $-0x8, %r15
jne 0xaf94
movslq 0x34(%r12), %rax
testq %rax, %rax
leaq 0x34(%rax,%r12), %r13
cmoveq %rax, %r13
movslq 0x30(%r12), %r12
testq %r12, %r12
je 0xb048
shlq $0x3, %r12
movq %r13, %r15
movl 0x4(%r13), %ebp
movslq (%r13), %rax
leaq (%r15,%rax), %rdx
testq %rax, %rax
cmoveq %rax, %rdx
movq %r14, %rdi
movl %ebp, %esi
callq 0x890c
cmpl $-0x1, %eax
jne 0xb03a
movslq (%r13), %rax
leaq (%r15,%rax), %rdx
testq %rax, %rax
cmoveq %rax, %rdx
movq %r14, %rdi
movl %ebp, %esi
callq 0xd609
addq $0x8, %r13
addq $0x8, %r15
addq $-0x8, %r12
jne 0xafff
movq 0x28(%rsp), %rdx
incq %rdx
cmpq 0x58(%rsp), %rdx
jne 0xaf53
movq 0x8(%rsp), %r13
leaq 0x8(%r13), %rdi
leaq 0x30(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0xc(%rax)
movaps %xmm0, (%rax)
movq %r13, 0x20(%rax)
leaq 0x60(%rsp), %rcx
movq %rcx, 0xa0(%rsp)
movq %rax, 0xa8(%rsp)
movq %rdi, 0xb0(%rsp)
movq 0x20(%rsp), %rcx
movslq 0x4(%rcx), %rax
movq %rax, 0x28(%rsp)
testq %rax, %rax
jle 0xb1a5
movq %rdi, 0x18(%rsp)
addq $0xc, %rcx
xorl %r12d, %r12d
leaq 0xa0(%rsp), %r15
movq %rcx, 0x20(%rsp)
movslq (%rcx), %rax
addq %rax, %rcx
testq %rax, %rax
cmoveq %rax, %rcx
leaq (%r12,%r12,8), %rax
leaq (%rcx,%rax,4), %r13
movslq 0x18(%rcx,%rax,4), %rdx
testq %rdx, %rdx
leaq 0x18(%rdx,%r13), %rbp
cmoveq %rdx, %rbp
movslq 0x14(%rcx,%rax,4), %r14
testq %r14, %r14
je 0xb11e
shlq $0x2, %r14
xorl %ebx, %ebx
leaq (%rbx,%rbp), %rsi
movslq (%rbp,%rbx), %rax
addq %rax, %rsi
testq %rax, %rax
cmoveq %rax, %rsi
movq %r15, %rdi
callq 0xb348
addq $0x4, %rbx
cmpq %rbx, %r14
jne 0xb0fa
movslq 0x20(%r13), %rax
testq %rax, %rax
leaq 0x20(%rax,%r13), %rbp
cmoveq %rax, %rbp
movslq 0x1c(%r13), %r13
testq %r13, %r13
je 0xb162
shlq $0x2, %r13
xorl %r14d, %r14d
leaq (%r14,%rbp), %rsi
movslq (%rbp,%r14), %rax
addq %rax, %rsi
testq %rax, %rax
cmoveq %rax, %rsi
movq %r15, %rdi
callq 0xb348
addq $0x4, %r14
cmpq %r14, %r13
jne 0xb13e
incq %r12
cmpq 0x28(%rsp), %r12
movq 0x20(%rsp), %rcx
jne 0xb0c4
movl 0x48(%rsp), %esi
shlq $0x3, %rsi
movq 0x8(%rsp), %r13
movq (%rsp), %rbp
movq 0x18(%rsp), %rdi
jmp 0xb1ab
leaq 0xb552(%rip), %rsi      # 0x166e6
movl $0x8, %edi
xorl %eax, %eax
callq 0x5d74
jmp 0xb2d7
xorl %esi, %esi
movq (%rsp), %rbp
movl $0x8, %edx
callq 0xe950
movq %rax, %r14
movl 0x40(%rsp), %eax
testq %rax, %rax
je 0xb1ea
movq 0x30(%rsp), %rcx
movq 0x38(%rsp), %rdx
xorl %esi, %esi
xorl %edi, %edi
cmpl $0x0, (%rcx,%rsi,4)
je 0xb1e2
movq (%rdx,%rsi,8), %r8
movl %edi, %r9d
movq %r8, (%r14,%r9,8)
incl %edi
incq %rsi
cmpq %rsi, %rax
jne 0xb1cf
movl 0x48(%rsp), %ebx
testq %rbx, %rbx
je 0xb288
leaq (%r14,%rbx,8), %r15
bsrq %rbx, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r14, %rdi
movq %r15, %rsi
callq 0xcece
cmpl $0x11, %ebx
jb 0xb246
shlq $0x3, %rbx
movq %r14, %r15
subq $-0x80, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0xd1cd
addq $-0x80, %rbx
movq %r15, %rdi
callq 0xd248
addq $0x8, %r15
addq $-0x8, %rbx
jne 0xb232
jmp 0xb251
movq %r14, %rdi
movq %r15, %rsi
callq 0xd1cd
movl 0x48(%rsp), %ebx
testq %rbx, %rbx
je 0xb288
leaq 0xb4c5(%rip), %r15      # 0x16726
xorl %r12d, %r12d
movq (%r14,%r12,8), %rdx
movl $0x8, %edi
movq %r15, %rsi
xorl %eax, %eax
callq 0x5d74
movq (%r14,%r12,8), %rdi
callq 0x6047
incq %r12
cmpq %r12, %rbx
jne 0xb264
movq 0x30(%rsp), %rsi
movq 0x50(%rsp), %rdi
callq 0xe88a
movq 0x38(%rsp), %rsi
movq 0x50(%rsp), %rdi
callq 0xe88a
xorps %xmm0, %xmm0
movups %xmm0, 0x3c(%rsp)
movaps %xmm0, 0x30(%rsp)
movq 0x60(%rsp), %rsi
movq 0x80(%rsp), %rdi
callq 0xe88a
movq 0x68(%rsp), %rsi
movq 0x80(%rsp), %rdi
callq 0xe88a
movq %rbp, 0x20(%r13)
leaq 0x14(%rsp), %rdi
callq 0x5a06
leaq 0x88(%rsp), %rdi
callq 0x5a30
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
jmp 0xb324
movq %rax, %r14
jmp 0xb332
jmp 0xb318
jmp 0xb318
jmp 0xb318
jmp 0xb318
jmp 0xb318
movq %rax, %r14
movq 0x8(%rsp), %r13
movq (%rsp), %rbp
movq %rbp, 0x20(%r13)
leaq 0x14(%rsp), %rdi
callq 0x5a06
leaq 0x88(%rsp), %rdi
callq 0x5a30
movq %r14, %rdi
callq 0x35e0
nop