// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x200, %rsp            # imm = 0x200
movq %rdi, -0x8(%rbp)
leaq 0x1fe8a(%rip), %rdx     # 0x2f610
xorl %eax, %eax
movl %eax, -0x198(%rbp)
movl %eax, %esi
leaq -0x20(%rbp), %rdi
callq 0x7220
movl -0x198(%rbp), %edx
leaq 0x14faa(%rip), %rsi     # 0x24750
leaq -0x24(%rbp), %rdi
callq 0x67e0
jmp 0xf7b1
movq -0x8(%rbp), %rax
movq 0xa0(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0xa8(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x6e40
jmp 0xf7ea
cmpq $0x0, -0x48(%rbp)
jne 0xf84e
leaq 0x14f72(%rip), %rsi     # 0x2476a
xorl %eax, %eax
movl $0x8, %edi
callq 0x7a60
jmp 0xf806
movl $0x1, -0x64(%rbp)
jmp 0xfd34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xfd61
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xfd58
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x6f50
jmp 0xfd58
movq -0x8(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0x14960
jmp 0xf860
leaq -0x90(%rbp), %rax
movq %rax, -0x98(%rbp)
movl $0x0, -0x9c(%rbp)
movq -0x40(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0xa0(%rbp)
movl -0x9c(%rbp), %eax
cmpl -0xa0(%rbp), %eax
jge 0xfa22
movq -0x40(%rbp), %rdi
addq $0xc, %rdi
callq 0x144d0
movq %rax, -0x1a0(%rbp)
jmp 0xf8ad
movq -0x1a0(%rbp), %rax
movslq -0x9c(%rbp), %rcx
leaq (%rcx,%rcx,8), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
addq $0x28, %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x6e90
movq %rax, -0x1a8(%rbp)
jmp 0xf8f1
movq -0x1a8(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x6eb0
movq %rax, -0x1b0(%rbp)
jmp 0xf914
movq -0x1b0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xb8(%rbp), %rax
cmpq -0xc0(%rbp), %rax
je 0xf96b
movq -0xb8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0xfd80
jmp 0xf955
jmp 0xf957
movq -0xb8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0xb8(%rbp)
jmp 0xf922
movq -0xa8(%rbp), %rax
addq $0x30, %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x6e90
movq %rax, -0x1b8(%rbp)
jmp 0xf992
movq -0x1b8(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x6eb0
movq %rax, -0x1c0(%rbp)
jmp 0xf9b5
movq -0x1c0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xd8(%rbp), %rax
cmpq -0xe0(%rbp), %rax
je 0xfa0c
movq -0xd8(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0xfd80
jmp 0xf9f6
jmp 0xf9f8
movq -0xd8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0xd8(%rbp)
jmp 0xf9c3
jmp 0xfa0e
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0xf885
movq -0x8(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0x14960
jmp 0xfa34
leaq -0x90(%rbp), %rax
movq %rax, -0x128(%rbp)
leaq -0x110(%rbp), %rax
movq %rax, -0x120(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x118(%rbp)
movl $0x0, -0x12c(%rbp)
movq -0x48(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x130(%rbp)
movl -0x12c(%rbp), %eax
cmpl -0x130(%rbp), %eax
jge 0xfc39
movq -0x48(%rbp), %rdi
addq $0xc, %rdi
callq 0x14690
movq %rax, -0x1c8(%rbp)
jmp 0xfa9a
movq -0x1c8(%rbp), %rax
movslq -0x12c(%rbp), %rcx
leaq (%rcx,%rcx,8), %rcx
leaq (%rax,%rcx,4), %rax
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
addq $0x14, %rax
movq %rax, -0x140(%rbp)
movq -0x140(%rbp), %rdi
callq 0x14990
movq %rax, -0x1d0(%rbp)
jmp 0xfade
movq -0x1d0(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x140(%rbp), %rdi
callq 0x149b0
movq %rax, -0x1d8(%rbp)
jmp 0xfb01
movq -0x1d8(%rbp), %rax
movq %rax, -0x150(%rbp)
movq -0x148(%rbp), %rax
cmpq -0x150(%rbp), %rax
je 0xfb6d
movq -0x148(%rbp), %rdi
callq 0x6e20
movq %rax, -0x1e0(%rbp)
jmp 0xfb34
movq -0x1e0(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0x158(%rbp), %rsi
leaq -0x128(%rbp), %rdi
callq 0xfe00
jmp 0xfb57
jmp 0xfb59
movq -0x148(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x148(%rbp)
jmp 0xfb0f
movq -0x138(%rbp), %rax
addq $0x1c, %rax
movq %rax, -0x160(%rbp)
movq -0x160(%rbp), %rdi
callq 0x14990
movq %rax, -0x1e8(%rbp)
jmp 0xfb94
movq -0x1e8(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x160(%rbp), %rdi
callq 0x149b0
movq %rax, -0x1f0(%rbp)
jmp 0xfbb7
movq -0x1f0(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x168(%rbp), %rax
cmpq -0x170(%rbp), %rax
je 0xfc23
movq -0x168(%rbp), %rdi
callq 0x6e20
movq %rax, -0x1f8(%rbp)
jmp 0xfbea
movq -0x1f8(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0x178(%rbp), %rsi
leaq -0x128(%rbp), %rdi
callq 0xfe00
jmp 0xfc0d
jmp 0xfc0f
movq -0x168(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x168(%rbp)
jmp 0xfbc5
jmp 0xfc25
movl -0x12c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x12c(%rbp)
jmp 0xfa72
movq -0x50(%rbp), %rdi
movl -0xf8(%rbp), %eax
movl %eax, %esi
callq 0x149f0
movq %rax, -0x200(%rbp)
jmp 0xfc53
movq -0x200(%rbp), %rax
movq %rax, -0x180(%rbp)
movq -0x180(%rbp), %rax
movq %rax, -0x188(%rbp)
movq -0x188(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0xff50
jmp 0xfc84
movq -0x180(%rbp), %rdi
movl -0xf8(%rbp), %eax
leaq (%rdi,%rax,8), %rsi
callq 0xfff0
jmp 0xfc9c
movl $0x0, -0x190(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, -0x194(%rbp)
movl -0x190(%rbp), %eax
cmpl -0x194(%rbp), %eax
jae 0xfd11
movq -0x180(%rbp), %rax
movl -0x190(%rbp), %ecx
movq (%rax,%rcx,8), %rdx
leaq 0x14ad2(%rip), %rsi     # 0x247aa
xorl %eax, %eax
movl $0x8, %edi
callq 0x7a60
jmp 0xfce6
movq -0x180(%rbp), %rax
movl -0x190(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
callq 0x7ef0
jmp 0xfcfe
jmp 0xfd00
movl -0x190(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x190(%rbp)
jmp 0xfcb2
leaq -0x110(%rbp), %rdi
callq 0x14a20
jmp 0xfd1f
leaq -0x90(%rbp), %rdi
callq 0x14a20
jmp 0xfd2d
movl $0x0, -0x64(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x6f50
leaq -0x24(%rbp), %rdi
callq 0x6980
leaq -0x20(%rbp), %rdi
callq 0x7270
addq $0x200, %rsp            # imm = 0x200
popq %rbp
retq
leaq -0x24(%rbp), %rdi
callq 0x6980
leaq -0x20(%rbp), %rdi
callq 0x7270
movq -0x30(%rbp), %rdi
callq 0x35c0
nopw %cs:(%rax,%rax)