// File: /workspace/github_cpp_makefile_star2_O1/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdi, %rbx
leaq 0x50(%rsp), %rax
movq %rax, -0x30(%rax)
movq $0x1, -0x28(%rax)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, -0x10(%rax) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movq 0x30(%rsi), %r14
addq $0x30, %rsi
movq %rsi, 0x10(%rsp)
cmpq %rsi, %r14
je 0x497cf
leaq 0x20(%rsp), %r15
movq 0x10(%r14), %r12
movq 0x28(%r12), %r13
addq $0x28, %r12
cmpq %r12, %r13
je 0x497c5
movq 0x10(%r13), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x49d0a
testb %al, %al
jne 0x497bf
movq %rbp, (%rsp)
movq %r15, 0x8(%rsp)
movq %r15, %rdi
movq %rsp, %rsi
leaq 0x8(%rsp), %rdx
callq 0x4a158
movq (%r13), %r13
jmp 0x4978e
movq (%r14), %r14
cmpq 0x10(%rsp), %r14
jne 0x49781
cmpq $0x0, 0x38(%rsp)
je 0x4989a
leaq 0x20(%rsp), %r14
movq %rsp, %r13
leaq 0x45c0e(%rip), %r15     # 0x8f3f8
movq 0x30(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, (%rsp)
movq 0x60(%rax), %r12
movq %r14, %rdi
movq %r13, %rsi
callq 0x4a41e
movq (%rsp), %rax
leaq 0x10(%rax), %rcx
cmpq %rcx, 0x10(%rax)
jne 0x4988e
movq 0x48(%rax), %r13
movq 0x50(%rax), %rbp
cmpq %rbp, %r13
je 0x49870
movq (%r13), %rdi
testq %rdi, %rdi
je 0x49840
leaq 0x45c7f(%rip), %rsi     # 0x8f4b0
movq %r15, %rdx
xorl %ecx, %ecx
callq 0x8320
movq %rax, %rsi
jmp 0x49842
xorl %esi, %esi
movq %rsi, 0x18(%rsp)
movq %rbx, %rdi
callq 0x49d0a
testb %al, %al
jne 0x4986a
movq %r14, 0x8(%rsp)
movq %r14, %rdi
leaq 0x18(%rsp), %rsi
leaq 0x8(%rsp), %rdx
callq 0x4a158
addq $0x10, %r13
jmp 0x4981c
movq (%rsp), %rsi
movq %r12, %rdi
callq 0x35966
movq %rsp, %r13
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x4988e
movq (%rdi), %rax
callq *0x8(%rax)
cmpq $0x0, 0x38(%rsp)
jne 0x497ea
leaq 0x20(%rsp), %rdi
callq 0x4a002
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x498b9
jmp 0x498b9
jmp 0x498b9
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x4a002
movq %rbx, %rdi
callq 0x8540