// File: luooofan[P]hblzbd_compiler/src/Pass/dead_code_eliminate.cpp
// Function: DeadCodeEliminate::DeleteDeadStore(SSAFunction*)
void DeadCodeEliminate::DeleteDeadStore(SSAFunction* func) {
#ifdef DEBUG_DEAD_STORE_ELIMINATE_PROCESS
  std::cout << "Dead Store Eliminate for Function: " << func->GetFuncName() << std::endl;
#endif

  for (auto bb : func->GetBasicBlocks()) {
#ifdef DEBUG_DEAD_STORE_ELIMINATE_PROCESS
    std::cout << "  BB: " << bb->GetLabel() << std::endl;
#endif

    for (auto it = bb->GetInstList().begin(); it != bb->GetInstList().end(); ++it) {
      auto store_inst = dynamic_cast<StoreInst*>(*it);
      if (nullptr != store_inst) {
        auto it2 = ++it;
        --it;
        for (; it2 != bb->GetInstList().end(); ++it2) {
          // 如果是一条load指令 并且操作同一块内存区域 除非两个都是立即数且不相同 否则直接break
          if (auto src_inst = dynamic_cast<LoadInst*>(*it2)) {
            if (store_inst->GetNumOperands() - 1 == src_inst->GetNumOperands() &&
                src_inst->GetOperand(0) == store_inst->GetOperand(1)) {
              if (store_inst->GetNumOperands() == 3) {
                auto constint = dynamic_cast<ConstantInt*>(store_inst->GetOperand(2));
                auto constint2 = dynamic_cast<ConstantInt*>(src_inst->GetOperand(1));
                if (nullptr != constint && nullptr != constint2 && constint->GetImm() != constint2->GetImm()) {
                  continue;
                }
              }
              break;
            }
          }
          // 如果是一条call指令 并且调用的是有副作用的函数 直接break
          else if (auto src_inst = dynamic_cast<CallInst*>(*it2)) {
            if (!no_side_effect_funcs.count(dynamic_cast<FunctionValue*>(src_inst->GetOperand(0))->GetFunction()))
              break;
          }
          // 如果是一条操作同一内存位置的store指令 则前面这条store可删除
          else if (auto src_inst = dynamic_cast<StoreInst*>(*it2)) {
            if (store_inst->GetNumOperands() == src_inst->GetNumOperands() &&
                src_inst->GetOperand(1) == store_inst->GetOperand(1)) {
              if (store_inst->GetNumOperands() == 3) {
                auto constint = dynamic_cast<ConstantInt*>(store_inst->GetOperand(2));
                auto constint2 = dynamic_cast<ConstantInt*>(src_inst->GetOperand(2));
                if (store_inst->GetOperand(2) == src_inst->GetOperand(2) ||
                    (nullptr != constint && nullptr != constint2 && constint->GetImm() == constint2->GetImm())) {
#ifdef DEBUG_DEAD_STORE_ELIMINATE_PROCESS
                  std::cout << "  find dead store: ", store_inst->Print(std::cout);
                  std::cout << "               ==> ", src_inst->Print(std::cout);
#endif

                  it = bb->GetInstList().erase(it);
                  --it;
                  delete store_inst;
                  break;
                }
              } else {
#ifdef DEBUG_DEAD_STORE_ELIMINATE_PROCESS
                std::cout << "  find dead store: ", store_inst->Print(std::cout);
                std::cout << "               ==> ", src_inst->Print(std::cout);
#endif

                it = bb->GetInstList().erase(it);
                --it;
                delete store_inst;
                break;
              }
            }
          }
        }
      }
    }
  }
}

// Assembly:
subq $0x1b8, %rsp            # imm = 0x1B8
movq %rdi, 0x1b0(%rsp)
movq %rsi, 0x1a8(%rsp)
movq 0x1b0(%rsp), %rax
movq %rax, 0xf8(%rsp)
movq 0x1a8(%rsp), %rdi
callq 0xa0f90
movq %rax, 0x1a0(%rsp)
movq 0x1a0(%rsp), %rdi
callq 0x62720
movq %rax, 0x198(%rsp)
movq 0x1a0(%rsp), %rdi
callq 0x62750
movq %rax, 0x190(%rsp)
leaq 0x198(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0x62780
testb $0x1, %al
jne 0xa0174
jmp 0xa0938
leaq 0x198(%rsp), %rdi
callq 0x627a0
movq (%rax), %rax
movq %rax, 0x188(%rsp)
movq 0x188(%rsp), %rdi
callq 0x62860
movq %rax, %rdi
callq 0x62870
movq %rax, 0x180(%rsp)
movq 0x188(%rsp), %rdi
callq 0x62860
movq %rax, %rdi
callq 0x628a0
movq %rax, 0x178(%rsp)
leaq 0x180(%rsp), %rdi
leaq 0x178(%rsp), %rsi
callq 0x628d0
testb $0x1, %al
jne 0xa01e4
jmp 0xa0924
leaq 0x180(%rsp), %rdi
callq 0x628f0
movq (%rax), %rax
movq %rax, 0xf0(%rsp)
cmpq $0x0, %rax
je 0xa022b
movq 0xf0(%rsp), %rdi
leaq 0xab207(%rip), %rsi     # 0x14b418
leaq 0xab5f8(%rip), %rdx     # 0x14b810
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0xe8(%rsp)
jmp 0xa0237
xorl %eax, %eax
movq %rax, 0xe8(%rsp)
jmp 0xa0237
movq 0xe8(%rsp), %rax
movq %rax, 0x170(%rsp)
xorl %eax, %eax
cmpq 0x170(%rsp), %rax
je 0xa0910
leaq 0x180(%rsp), %rdi
callq 0x62960
movq (%rax), %rax
movq %rax, 0x168(%rsp)
leaq 0x180(%rsp), %rdi
callq 0xa1220
movq 0x188(%rsp), %rdi
callq 0x62860
movq %rax, %rdi
callq 0x628a0
movq %rax, 0x160(%rsp)
leaq 0x168(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0x628d0
testb $0x1, %al
jne 0xa02b7
jmp 0xa090e
leaq 0x168(%rsp), %rdi
callq 0x628f0
movq (%rax), %rax
movq %rax, 0xe0(%rsp)
cmpq $0x0, %rax
je 0xa02fe
movq 0xe0(%rsp), %rdi
leaq 0xab134(%rip), %rsi     # 0x14b418
leaq 0xab4e5(%rip), %rdx     # 0x14b7d0
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0xd8(%rsp)
jmp 0xa030a
xorl %eax, %eax
movq %rax, 0xd8(%rsp)
jmp 0xa030a
movq 0xd8(%rsp), %rax
movq %rax, 0x158(%rsp)
cmpq $0x0, 0x158(%rsp)
je 0xa04d2
movq 0x170(%rsp), %rdi
callq 0x5e580
subl $0x1, %eax
movl %eax, 0xd4(%rsp)
movq 0x158(%rsp), %rdi
callq 0x5e580
movl %eax, %ecx
movl 0xd4(%rsp), %eax
cmpl %ecx, %eax
jne 0xa04cd
movq 0x158(%rsp), %rdi
xorl %esi, %esi
callq 0x5c850
movq %rax, 0xc8(%rsp)
movq 0x170(%rsp), %rdi
movl $0x1, %esi
callq 0x5c850
movq %rax, %rcx
movq 0xc8(%rsp), %rax
cmpq %rcx, %rax
jne 0xa04cd
movq 0x170(%rsp), %rdi
callq 0x5e580
cmpl $0x3, %eax
jne 0xa04c8
movq 0x170(%rsp), %rdi
movl $0x2, %esi
callq 0x5c850
movq %rax, 0xc0(%rsp)
cmpq $0x0, %rax
je 0xa03fa
movq 0xc0(%rsp), %rdi
leaq 0xab0f0(%rip), %rsi     # 0x14b4d0
leaq 0xab111(%rip), %rdx     # 0x14b4f8
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0xb8(%rsp)
jmp 0xa0406
xorl %eax, %eax
movq %rax, 0xb8(%rsp)
jmp 0xa0406
movq 0xb8(%rsp), %rax
movq %rax, 0x150(%rsp)
movq 0x158(%rsp), %rdi
movl $0x1, %esi
callq 0x5c850
movq %rax, 0xb0(%rsp)
cmpq $0x0, %rax
je 0xa045f
movq 0xb0(%rsp), %rdi
leaq 0xab08b(%rip), %rsi     # 0x14b4d0
leaq 0xab0ac(%rip), %rdx     # 0x14b4f8
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0xa8(%rsp)
jmp 0xa046b
xorl %eax, %eax
movq %rax, 0xa8(%rsp)
jmp 0xa046b
movq 0xa8(%rsp), %rax
movq %rax, 0x148(%rsp)
xorl %eax, %eax
cmpq 0x150(%rsp), %rax
je 0xa04c6
xorl %eax, %eax
cmpq 0x148(%rsp), %rax
je 0xa04c6
movq 0x150(%rsp), %rdi
callq 0x5e800
movl %eax, 0xa4(%rsp)
movq 0x148(%rsp), %rdi
callq 0x5e800
movl %eax, %ecx
movl 0xa4(%rsp), %eax
cmpl %ecx, %eax
je 0xa04c6
jmp 0xa08fc
jmp 0xa04c8
jmp 0xa090e
jmp 0xa08fa
leaq 0x168(%rsp), %rdi
callq 0x628f0
movq (%rax), %rax
movq %rax, 0x98(%rsp)
cmpq $0x0, %rax
je 0xa0519
movq 0x98(%rsp), %rdi
leaq 0xaaf19(%rip), %rsi     # 0x14b418
leaq 0xab20a(%rip), %rdx     # 0x14b710
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x90(%rsp)
jmp 0xa0525
xorl %eax, %eax
movq %rax, 0x90(%rsp)
jmp 0xa0525
movq 0x90(%rsp), %rax
movq %rax, 0x140(%rsp)
cmpq $0x0, 0x140(%rsp)
je 0xa05e4
movq 0xf8(%rsp), %rax
addq $0x38, %rax
movq %rax, 0x80(%rsp)
movq 0x140(%rsp), %rdi
xorl %esi, %esi
callq 0x5c850
movq %rax, 0x88(%rsp)
cmpq $0x0, %rax
je 0xa059b
movq 0x88(%rsp), %rdi
leaq 0xaaf4c(%rip), %rsi     # 0x14b4d0
leaq 0xaaf9d(%rip), %rdx     # 0x14b528
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x78(%rsp)
jmp 0xa05a4
xorl %eax, %eax
movq %rax, 0x78(%rsp)
jmp 0xa05a4
movq 0x78(%rsp), %rdi
callq 0x5e2a0
movq 0x80(%rsp), %rdi
movq %rax, 0x138(%rsp)
leaq 0x138(%rsp), %rsi
callq 0xa1240
cmpq $0x0, %rax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xa05da
jmp 0xa05df
jmp 0xa090e
jmp 0xa08f8
leaq 0x168(%rsp), %rdi
callq 0x628f0
movq (%rax), %rax
movq %rax, 0x70(%rsp)
cmpq $0x0, %rax
je 0xa0622
movq 0x70(%rsp), %rdi
leaq 0xaae0d(%rip), %rsi     # 0x14b418
leaq 0xab1fe(%rip), %rdx     # 0x14b810
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x68(%rsp)
jmp 0xa062b
xorl %eax, %eax
movq %rax, 0x68(%rsp)
jmp 0xa062b
movq 0x68(%rsp), %rax
movq %rax, 0x130(%rsp)
cmpq $0x0, 0x130(%rsp)
je 0xa08f6
movq 0x170(%rsp), %rdi
callq 0x5e580
movl %eax, 0x64(%rsp)
movq 0x130(%rsp), %rdi
callq 0x5e580
movl %eax, %ecx
movl 0x64(%rsp), %eax
cmpl %ecx, %eax
jne 0xa08f4
movq 0x130(%rsp), %rdi
movl $0x1, %esi
callq 0x5c850
movq %rax, 0x58(%rsp)
movq 0x170(%rsp), %rdi
movl $0x1, %esi
callq 0x5c850
movq %rax, %rcx
movq 0x58(%rsp), %rax
cmpq %rcx, %rax
jne 0xa08f4
movq 0x170(%rsp), %rdi
callq 0x5e580
cmpl $0x3, %eax
jne 0xa0874
movq 0x170(%rsp), %rdi
movl $0x2, %esi
callq 0x5c850
movq %rax, 0x50(%rsp)
cmpq $0x0, %rax
je 0xa0703
movq 0x50(%rsp), %rdi
leaq 0xaade4(%rip), %rsi     # 0x14b4d0
leaq 0xaae05(%rip), %rdx     # 0x14b4f8
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x48(%rsp)
jmp 0xa070c
xorl %eax, %eax
movq %rax, 0x48(%rsp)
jmp 0xa070c
movq 0x48(%rsp), %rax
movq %rax, 0x128(%rsp)
movq 0x130(%rsp), %rdi
movl $0x2, %esi
callq 0x5c850
movq %rax, 0x40(%rsp)
cmpq $0x0, %rax
je 0xa0759
movq 0x40(%rsp), %rdi
leaq 0xaad8e(%rip), %rsi     # 0x14b4d0
leaq 0xaadaf(%rip), %rdx     # 0x14b4f8
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x38(%rsp)
jmp 0xa0762
xorl %eax, %eax
movq %rax, 0x38(%rsp)
jmp 0xa0762
movq 0x38(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x170(%rsp), %rdi
movl $0x2, %esi
callq 0x5c850
movq %rax, 0x30(%rsp)
movq 0x130(%rsp), %rdi
movl $0x2, %esi
callq 0x5c850
movq %rax, %rcx
movq 0x30(%rsp), %rax
cmpq %rcx, %rax
je 0xa07f1
xorl %eax, %eax
cmpq 0x128(%rsp), %rax
je 0xa0872
xorl %eax, %eax
cmpq 0x120(%rsp), %rax
je 0xa0872
movq 0x128(%rsp), %rdi
callq 0x5e800
movl %eax, 0x2c(%rsp)
movq 0x120(%rsp), %rdi
callq 0x5e800
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jne 0xa0872
movq 0x188(%rsp), %rdi
callq 0x62860
movq %rax, 0x18(%rsp)
leaq 0x110(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0x62e90
movq 0x18(%rsp), %rdi
movq 0x110(%rsp), %rsi
callq 0xa1270
movq %rax, 0x118(%rsp)
movq 0x118(%rsp), %rax
movq %rax, 0x180(%rsp)
leaq 0x180(%rsp), %rdi
callq 0xa1220
movq 0x170(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0xa086d
movq 0x20(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0xa090e
jmp 0xa08f2
movq 0x188(%rsp), %rdi
callq 0x62860
movq %rax, 0x8(%rsp)
leaq 0x100(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0x62e90
movq 0x8(%rsp), %rdi
movq 0x100(%rsp), %rsi
callq 0xa1270
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rax
movq %rax, 0x180(%rsp)
leaq 0x180(%rsp), %rdi
callq 0xa1220
movq 0x170(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0xa08f0
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0xa090e
jmp 0xa08f4
jmp 0xa08f6
jmp 0xa08f8
jmp 0xa08fa
jmp 0xa08fc
leaq 0x168(%rsp), %rdi
callq 0x62960
jmp 0xa027c
jmp 0xa0910
jmp 0xa0912
leaq 0x180(%rsp), %rdi
callq 0x62960
jmp 0xa01a9
jmp 0xa0926
leaq 0x198(%rsp), %rdi
callq 0x627f0
jmp 0xa0156
addq $0x1b8, %rsp            # imm = 0x1B8
retq