// File: luooofan[P]hblzbd_compiler/src/Pass/dead_code_eliminate.cpp
// Function: DeadCodeEliminate::DeleteDeadInst(SSAFunction*)
void DeadCodeEliminate::DeleteDeadInst(SSAFunction* func) {
#ifdef DEBUG_DEAD_CODE_ELIMINATE_PROCESS
  std::cout << "Try To Remove Instruction in function: " << func->GetFuncName() << std::endl;
#endif
  // 没有使用过的一个定值value 如果其定值语句没有副作用 就可删除
  std::unordered_set<SSAInstruction*> worklist;
  for (auto bb : func->GetBasicBlocks()) {
    for (auto inst : bb->GetInstList()) {
      // 把有定值的 无副作用的语句加入到工作表中 有的指令是一次定值(在ssa.h中指定了[used]的) 有的不是([no used])
      if (!IsSideEffect(inst)) worklist.insert({inst});
    }
  }

  while (!worklist.empty()) {
    auto inst = *worklist.begin();
    auto bb = inst->GetParent();
    worklist.erase(inst);
    if (inst->IsUsed()) continue;
#ifdef DEBUG_DEAD_CODE_ELIMINATE_PROCESS
    std::cout << "  remove: ";
    inst->Print(std::cout);
#endif
    // 其使用可能优化
    for (auto& use : inst->GetOperands()) {
      auto src_inst = dynamic_cast<SSAInstruction*>(use.Get());
      if (!IsSideEffect(src_inst)) {
        worklist.insert(src_inst);
      }
    }
    bb->RemoveInstruction(inst);  // FIXME 只是从指令列表中移除 并未释放内存
    delete inst;  // delete会删除inst的所有操作数 移除其操作数对应的使用 还会维护所有被使用信息
  }
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x160(%rsp)
movq %rsi, 0x158(%rsp)
movq 0x160(%rsp), %rax
movq %rax, 0x58(%rsp)
leaq 0x120(%rsp), %rdi
callq 0xa0f80
movq 0x158(%rsp), %rdi
callq 0xa0f90
movq %rax, 0x60(%rsp)
jmp 0x9fd15
movq 0x60(%rsp), %rax
movq %rax, 0x118(%rsp)
movq 0x118(%rsp), %rdi
callq 0x62720
movq %rax, 0x100(%rsp)
movq 0x118(%rsp), %rdi
callq 0x62750
movq %rax, 0xf8(%rsp)
leaq 0x100(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x62780
testb $0x1, %al
jne 0x9fd6a
jmp 0x9fec0
leaq 0x100(%rsp), %rdi
callq 0x627a0
movq (%rax), %rax
movq %rax, 0xf0(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x62860
movq %rax, 0x50(%rsp)
jmp 0x9fd96
movq 0x50(%rsp), %rax
movq %rax, 0xe8(%rsp)
movq 0xe8(%rsp), %rdi
callq 0x62870
movq %rax, 0xe0(%rsp)
movq 0xe8(%rsp), %rdi
callq 0x628a0
movq %rax, 0xd8(%rsp)
leaq 0xe0(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x628d0
testb $0x1, %al
jne 0x9fdeb
jmp 0x9feac
leaq 0xe0(%rsp), %rdi
callq 0x628f0
movq 0x58(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0xd0(%rsp)
movq 0xd0(%rsp), %rsi
callq 0xa09c0
movb %al, 0x4f(%rsp)
jmp 0x9fe1b
movb 0x4f(%rsp), %al
testb $0x1, %al
jne 0x9fe98
jmp 0x9fe25
movq 0xd0(%rsp), %rax
movq %rax, 0xb8(%rsp)
leaq 0xb8(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq $0x1, 0xc8(%rsp)
movq 0xc0(%rsp), %rsi
movq 0xc8(%rsp), %rdx
leaq 0x120(%rsp), %rdi
callq 0xa0fa0
jmp 0x9fe70
jmp 0x9fe98
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x110(%rsp)
movl %eax, 0x10c(%rsp)
leaq 0x120(%rsp), %rdi
callq 0xa10e0
jmp 0xa00e3
jmp 0x9fe9a
leaq 0xe0(%rsp), %rdi
callq 0x62960
jmp 0x9fdcd
jmp 0x9feae
leaq 0x100(%rsp), %rdi
callq 0x627f0
jmp 0x9fd4c
jmp 0x9fec2
leaq 0x120(%rsp), %rdi
callq 0xa0fe0
xorb $-0x1, %al
testb $0x1, %al
jne 0x9feda
jmp 0xa00ce
leaq 0x120(%rsp), %rdi
callq 0xa1000
movq %rax, 0xa8(%rsp)
leaq 0xa8(%rsp), %rdi
callq 0xa1030
movq (%rax), %rax
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rdi
callq 0x5e2b0
movq %rax, 0x40(%rsp)
jmp 0x9ff1b
movq 0x40(%rsp), %rax
movq %rax, 0xa0(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0xa1050
jmp 0x9ff3f
movq 0xb0(%rsp), %rdi
callq 0x5e3e0
movb %al, 0x3f(%rsp)
jmp 0x9ff52
movb 0x3f(%rsp), %al
testb $0x1, %al
jne 0x9ff5c
jmp 0x9ff61
jmp 0x9fec2
movq 0xb0(%rsp), %rdi
callq 0xa1080
movq %rax, 0x30(%rsp)
jmp 0x9ff75
movq 0x30(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x98(%rsp), %rdi
callq 0x5e630
movq %rax, 0x90(%rsp)
movq 0x98(%rsp), %rdi
callq 0x5e780
movq %rax, 0x88(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x5e7b0
testb $0x1, %al
jne 0x9ffca
jmp 0xa0096
leaq 0x90(%rsp), %rdi
callq 0x5e7f0
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rdi
callq 0x5e200
movq %rax, 0x28(%rsp)
jmp 0x9fff3
movq 0x28(%rsp), %rax
cmpq $0x0, %rax
je 0xa0021
movq 0x28(%rsp), %rdi
leaq 0xab4c6(%rip), %rsi     # 0x14b4d0
leaq 0xab407(%rip), %rdx     # 0x14b418
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x20(%rsp)
jmp 0xa002a
xorl %eax, %eax
movq %rax, 0x20(%rsp)
jmp 0xa002a
movq 0x58(%rsp), %rdi
movq 0x20(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rsi
callq 0xa09c0
movb %al, 0x1f(%rsp)
jmp 0xa0049
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0xa0082
jmp 0xa0053
leaq 0x120(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0xa1090
movb %dl, 0xf(%rsp)
movq %rax, 0x10(%rsp)
jmp 0xa0070
movb 0xf(%rsp), %al
movq 0x10(%rsp), %rcx
movq %rcx, 0x68(%rsp)
movb %al, 0x70(%rsp)
jmp 0xa0084
leaq 0x90(%rsp), %rdi
callq 0x5e920
jmp 0x9ffac
movq 0xa0(%rsp), %rdi
movq 0xb0(%rsp), %rsi
callq 0x619c0
jmp 0xa00ad
movq 0xb0(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0xa00c9
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x9fec2
leaq 0x120(%rsp), %rdi
callq 0xa10e0
addq $0x168, %rsp            # imm = 0x168
retq
movq 0x110(%rsp), %rdi
callq 0x8670