// File: /workspace/github_c_makefile_star2_O1/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, %rbx
movq $0x0, 0x88(%rsp)
leaq 0x123bf(%rip), %rax     # 0x1d620
movq %rax, 0x90(%rsp)
callq 0x60a6
movq %rax, 0x98(%rsp)
movl $0x0, 0xc(%rsp)
leaq 0x123fb(%rip), %rax     # 0x1d680
cmpb $0x1, (%rax)
jne 0xb298
leaq 0xb44b(%rip), %rdi      # 0x166dc
xorl %esi, %esi
callq 0xfb72
movq 0x20(%rbx), %r13
movq 0xa8(%rbx), %rax
movq %rax, 0x20(%rsp)
testq %rax, %rax
je 0xb5c0
movq %r13, 0x10(%rsp)
movq 0xa0(%rbx), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x6c(%rsp)
movaps %xmm0, 0x60(%rsp)
movq %rbx, (%rsp)
movq %rbx, 0x80(%rsp)
movq %rax, 0x18(%rsp)
movslq 0x4(%rax), %rax
movq %rax, 0x58(%rsp)
testq %rax, %rax
jle 0xb402
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 0xb384
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 0x8c89
cmpl $-0x1, %eax
jne 0xb376
movslq (%r13), %rax
leaq (%rbx,%rax), %rdx
testq %rax, %rax
cmoveq %rax, %rdx
movq %r14, %rdi
movl %ebp, %esi
callq 0xdb37
addq $0x8, %r13
addq $0x8, %rbx
addq $-0x8, %r15
jne 0xb33b
movslq 0x34(%r12), %rax
testq %rax, %rax
leaq 0x34(%rax,%r12), %r13
cmoveq %rax, %r13
movslq 0x30(%r12), %r15
testq %r15, %r15
je 0xb3ef
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 0x8c89
cmpl $-0x1, %eax
jne 0xb3e1
movslq (%r13), %rax
leaq (%rbx,%rax), %rdx
testq %rax, %rax
cmoveq %rax, %rdx
movq %r14, %rdi
movl %ebp, %esi
callq 0xdb37
addq $0x8, %r13
addq $0x8, %rbx
addq $-0x8, %r15
jne 0xb3a6
movq 0x28(%rsp), %rdx
incq %rdx
cmpq 0x58(%rsp), %rdx
jne 0xb2fa
movq (%rsp), %rcx
leaq 0x8(%rcx), %rdx
leaq 0x30(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0xc(%rax)
movaps %xmm0, (%rax)
movq %rcx, 0x20(%rax)
leaq 0x60(%rsp), %rcx
movq %rcx, 0xa0(%rsp)
movq %rax, 0xa8(%rsp)
movq %rdx, 0x18(%rsp)
movq %rdx, 0xb0(%rsp)
movq 0x20(%rsp), %rax
movslq 0x4(%rax), %rax
movq %rax, 0x28(%rsp)
testq %rax, %rax
jle 0xb517
addq $0xc, 0x20(%rsp)
xorl %r12d, %r12d
leaq 0xa0(%rsp), %r15
movq 0x20(%rsp), %rcx
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 0xb4c6
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 0xb6de
addq $0x4, %rbx
cmpq %rbx, %r14
jne 0xb4a2
movslq 0x20(%r13), %rax
testq %rax, %rax
leaq 0x20(%rax,%r13), %rbp
cmoveq %rax, %rbp
movslq 0x1c(%r13), %r14
testq %r14, %r14
je 0xb509
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 0xb6de
addq $0x4, %rbx
cmpq %rbx, %r14
jne 0xb4e5
incq %r12
cmpq 0x28(%rsp), %r12
jne 0xb467
movl 0x48(%rsp), %esi
shlq $0x3, %rsi
movl $0x8, %edx
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %r13
callq 0xf030
movq %rax, %r14
movl 0x40(%rsp), %eax
testq %rax, %rax
je 0xb568
movq 0x30(%rsp), %rcx
movq 0x38(%rsp), %rdx
xorl %esi, %esi
xorl %edi, %edi
cmpl $0x0, (%rcx,%rsi,4)
je 0xb560
movq (%rdx,%rsi,8), %r8
movl %edi, %r9d
movq %r8, (%r14,%r9,8)
incl %edi
incq %rsi
cmpq %rsi, %rax
jne 0xb54d
movl 0x48(%rsp), %ebx
testq %rbx, %rbx
je 0xb5e3
leaq (%r14,%rbx,8), %r15
bsrq %rbx, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r14, %rdi
movq %r15, %rsi
callq 0xd366
cmpl $0x11, %ebx
jb 0xb5d8
shlq $0x3, %rbx
movq %r14, %r15
subq $-0x80, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0xd68f
addq $-0x80, %rbx
movq %r15, %rdi
callq 0xd70a
addq $0x8, %r15
addq $-0x8, %rbx
jne 0xb5ac
jmp 0xb5e3
leaq 0xb12f(%rip), %rsi      # 0x166f6
movl $0x8, %edi
xorl %eax, %eax
callq 0x5ef0
jmp 0xb66d
movq %r14, %rdi
movq %r15, %rsi
callq 0xd68f
movl 0x48(%rsp), %ebx
testq %rbx, %rbx
je 0xb61a
leaq 0xb143(%rip), %r15      # 0x16736
xorl %r12d, %r12d
movq (%r14,%r12,8), %rdx
movl $0x8, %edi
movq %r15, %rsi
xorl %eax, %eax
callq 0x5ef0
movq (%r14,%r12,8), %rdi
callq 0x61c3
incq %r12
cmpq %r12, %rbx
jne 0xb5f6
movq 0x30(%rsp), %rsi
movq 0x50(%rsp), %rdi
callq 0xef6a
movq 0x38(%rsp), %rsi
movq 0x50(%rsp), %rdi
callq 0xef6a
xorps %xmm0, %xmm0
movups %xmm0, 0x3c(%rsp)
movaps %xmm0, 0x30(%rsp)
movq 0x60(%rsp), %rsi
movq 0x80(%rsp), %rdi
callq 0xef6a
movq 0x68(%rsp), %rsi
movq 0x80(%rsp), %rdi
callq 0xef6a
movq (%rsp), %rbx
movq %r13, 0x20(%rbx)
leaq 0xc(%rsp), %rdi
callq 0x5b82
leaq 0x88(%rsp), %rdi
callq 0x5bac
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
jmp 0xb6ba
movq %rax, %r14
jmp 0xb6c8
jmp 0xb6ae
jmp 0xb6ae
jmp 0xb6ae
jmp 0xb6ae
jmp 0xb6ae
movq %rax, %r14
movq (%rsp), %rbx
movq 0x10(%rsp), %r13
movq %r13, 0x20(%rbx)
leaq 0xc(%rsp), %rdi
callq 0x5b82
leaq 0x88(%rsp), %rdi
callq 0x5bac
movq %r14, %rdi
callq 0x35e0
nop