// File: luooofan[P]hblzbd_compiler/src/Pass/global_value_numbering.cpp
// Function: GlobalValueNumbering::Run()
void GlobalValueNumbering::Run() {
  kCount = 0;
  auto m = dynamic_cast<SSAModule*>(*(this->m_));
  MyAssert(nullptr != m);
  DeadCodeEliminate::FindNoSideEffectFunc(m, no_side_effect_funcs);

#ifdef DEBUG_GVN_PROCESS
  std::cout << "No side effect functions: ";
  for (auto func : no_side_effect_funcs) {
    std::cout << func->GetFuncName() << " ";
  }
  std::cout << std::endl;
#endif

  for (auto func : m->GetFuncList()) {
    // find back-edge
    std::set<std::pair<SSABasicBlock*, SSABasicBlock*>> back_edges;
    for (auto bb : func->GetBasicBlocks()) {
      auto&& dom_set = bb->GetDomSet();
      for (auto succ : bb->GetSuccBB()) {
        if (dom_set.count(succ)) back_edges.insert({bb, succ});
      }
    }
    // find loop and fill bbs_in_loop
    bbs_in_loop.clear();
    std::queue<SSABasicBlock*> q;
    std::unordered_set<SSABasicBlock*> loop;
    for (auto [st, ed] : back_edges) {
      MyAssert(q.empty() && loop.empty());
      loop.insert(ed);
      q.push(st);
      while (!q.empty()) {
        auto front = q.front();
        q.pop();
        if (loop.count(front)) continue;
        loop.insert(front);
        for (auto pred : front->GetPredBB()) q.push(pred);
      }
      bbs_in_loop.insert(loop.begin(), loop.end());
      loop.clear();
    }
    // prepared run for function
    exp_val_vec.clear();
    Run4Func(func);
  }

#ifdef DEBUG_GVN_EFFECT
  std::cout << "GVN Pass works on " << kCount << " insts" << std::endl;
#endif
}

// Assembly:
subq $0x2e8, %rsp            # imm = 0x2E8
movq %rdi, 0x2e0(%rsp)
movq 0x2e0(%rsp), %rax
movq %rax, 0xa8(%rsp)
movl $0x0, 0x92b8b(%rip)     # 0x14c794
movq 0x8(%rax), %rax
movq (%rax), %rax
movq %rax, 0xb0(%rsp)
cmpq $0x0, %rax
je 0xb9c47
movq 0xb0(%rsp), %rdi
leaq 0x909ab(%rip), %rsi     # 0x14a5d8
leaq 0x91d1c(%rip), %rdx     # 0x14b950
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0xa0(%rsp)
jmp 0xb9c53
xorl %eax, %eax
movq %rax, 0xa0(%rsp)
jmp 0xb9c53
movq 0xa0(%rsp), %rax
movq %rax, 0x2d8(%rsp)
xorl %eax, %eax
cmpq 0x2d8(%rsp), %rax
jne 0xb9cc6
movq 0x92372(%rip), %rdi     # 0x14bfe8
leaq 0x4047b(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, %rdi
leaq 0x43de3(%rip), %rsi     # 0xfda6f
callq 0x8330
movq %rax, %rdi
leaq 0x4174f(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, %rdi
movl $0x17, %esi
callq 0x8650
movq %rax, %rdi
movq 0x922c9(%rip), %rsi     # 0x14bf80
callq 0x8380
movl $0xff, %edi
callq 0x8460
movq 0xa8(%rsp), %rsi
movq 0x2d8(%rsp), %rdi
addq $0x38, %rsi
callq 0x9f6e0
movq 0x2d8(%rsp), %rdi
callq 0xa0ee0
movq %rax, 0x2d0(%rsp)
movq 0x2d0(%rsp), %rdi
callq 0x624d0
movq %rax, 0x2c8(%rsp)
movq 0x2d0(%rsp), %rdi
callq 0x62500
movq %rax, 0x2c0(%rsp)
leaq 0x2c8(%rsp), %rdi
leaq 0x2c0(%rsp), %rsi
callq 0x62530
testb $0x1, %al
jne 0xb9d3c
jmp 0xba3e0
leaq 0x2c8(%rsp), %rdi
callq 0x62550
movq (%rax), %rax
movq %rax, 0x2b8(%rsp)
leaq 0x288(%rsp), %rdi
callq 0xbd5e0
movq 0x2b8(%rsp), %rdi
callq 0xa0f90
movq %rax, 0x98(%rsp)
jmp 0xb9d78
movq 0x98(%rsp), %rax
movq %rax, 0x280(%rsp)
movq 0x280(%rsp), %rdi
callq 0x62720
movq %rax, 0x268(%rsp)
movq 0x280(%rsp), %rdi
callq 0x62750
movq %rax, 0x260(%rsp)
leaq 0x268(%rsp), %rdi
leaq 0x260(%rsp), %rsi
callq 0x62780
testb $0x1, %al
jne 0xb9dd0
jmp 0xb9f98
leaq 0x268(%rsp), %rdi
callq 0x627a0
movq (%rax), %rax
movq %rax, 0x258(%rsp)
movq 0x258(%rsp), %rsi
leaq 0x218(%rsp), %rdi
callq 0x619f0
jmp 0xb9dff
leaq 0x218(%rsp), %rax
movq %rax, 0x250(%rsp)
movq 0x258(%rsp), %rdi
callq 0x62810
movq %rax, 0x90(%rsp)
jmp 0xb9e26
movq 0x90(%rsp), %rax
movq %rax, 0x210(%rsp)
movq 0x210(%rsp), %rdi
callq 0x62720
movq %rax, 0x208(%rsp)
movq 0x210(%rsp), %rdi
callq 0x62750
movq %rax, 0x200(%rsp)
leaq 0x208(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x62780
testb $0x1, %al
jne 0xb9e7e
jmp 0xb9f79
leaq 0x208(%rsp), %rdi
callq 0x627a0
movq (%rax), %rax
movq %rax, 0x1f8(%rsp)
movq 0x250(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0xbd5f0
movq %rax, 0x88(%rsp)
jmp 0xb9eb5
movq 0x88(%rsp), %rax
cmpq $0x0, %rax
je 0xb9f65
leaq 0x1e8(%rsp), %rdi
leaq 0x258(%rsp), %rsi
leaq 0x1f8(%rsp), %rdx
callq 0xbd680
jmp 0xb9ee6
leaq 0x288(%rsp), %rdi
leaq 0x1e8(%rsp), %rsi
callq 0xbd620
movb %dl, 0x7f(%rsp)
movq %rax, 0x80(%rsp)
jmp 0xb9f09
movb 0x7f(%rsp), %al
movq 0x80(%rsp), %rcx
movq %rcx, 0x1d8(%rsp)
movb %al, 0x1e0(%rsp)
jmp 0xb9f65
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
jmp 0xba3d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
leaq 0x218(%rsp), %rdi
callq 0x63010
jmp 0xba3d1
jmp 0xb9f67
leaq 0x208(%rsp), %rdi
callq 0x627f0
jmp 0xb9e60
leaq 0x218(%rsp), %rdi
callq 0x63010
leaq 0x268(%rsp), %rdi
callq 0x627f0
jmp 0xb9db2
movq 0xa8(%rsp), %rdi
addq $0x70, %rdi
callq 0xbd6b0
leaq 0x188(%rsp), %rdi
callq 0xbd6c0
jmp 0xb9fb8
leaq 0x150(%rsp), %rdi
callq 0x50420
leaq 0x288(%rsp), %rax
movq %rax, 0x148(%rsp)
movq 0x148(%rsp), %rdi
callq 0xbd6f0
movq %rax, 0x140(%rsp)
movq 0x148(%rsp), %rdi
callq 0xbd720
movq %rax, 0x138(%rsp)
leaq 0x140(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0xbd750
testb $0x1, %al
jne 0xba01d
jmp 0xba36d
leaq 0x140(%rsp), %rdi
callq 0xbd770
movups (%rax), %xmm0
movaps %xmm0, 0x120(%rsp)
leaq 0x120(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0xbd790
movq 0x70(%rsp), %rdi
movq %rax, 0x118(%rsp)
callq 0xbd7a0
movq %rax, 0x110(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xbd7b0
movb %al, 0x7e(%rsp)
jmp 0xba074
movb 0x7e(%rsp), %al
testb $0x1, %al
jne 0xba07e
jmp 0xba093
leaq 0x150(%rsp), %rdi
callq 0xbd7d0
testb $0x1, %al
jne 0xba143
movq 0x91f4e(%rip), %rdi     # 0x14bfe8
leaq 0x40057(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, 0x68(%rsp)
jmp 0xba0ad
movq 0x68(%rsp), %rdi
leaq 0x439b6(%rip), %rsi     # 0xfda6f
callq 0x8330
movq %rax, 0x60(%rsp)
jmp 0xba0c5
movq 0x60(%rsp), %rdi
leaq 0x41319(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, 0x58(%rsp)
jmp 0xba0dd
movq 0x58(%rsp), %rdi
movl $0x30, %esi
callq 0x8650
movq %rax, 0x50(%rsp)
jmp 0xba0f3
movq 0x50(%rsp), %rdi
movq 0x91e81(%rip), %rsi     # 0x14bf80
callq 0x8380
jmp 0xba106
movl $0xff, %edi
callq 0x8460
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
leaq 0x150(%rsp), %rdi
callq 0x63010
leaq 0x188(%rsp), %rdi
callq 0xbd930
jmp 0xba3d1
movq 0x110(%rsp), %rsi
leaq 0x150(%rsp), %rdi
callq 0x62fb0
movb %dl, 0x47(%rsp)
movq %rax, 0x48(%rsp)
jmp 0xba163
movb 0x47(%rsp), %al
movq 0x48(%rsp), %rcx
movq %rcx, 0x100(%rsp)
movb %al, 0x108(%rsp)
movq 0x118(%rsp), %rsi
leaq 0x188(%rsp), %rdi
callq 0xbd7f0
jmp 0xba192
jmp 0xba194
leaq 0x188(%rsp), %rdi
callq 0xbd7b0
movb %al, 0x46(%rsp)
jmp 0xba1a7
movb 0x46(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xba1b6
jmp 0xba2f5
leaq 0x188(%rsp), %rdi
callq 0xbd820
movq %rax, 0x38(%rsp)
jmp 0xba1ca
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq %rax, 0xf8(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xbd830
jmp 0xba1e9
leaq 0x150(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0xbd5f0
movq %rax, 0x30(%rsp)
jmp 0xba205
movq 0x30(%rsp), %rax
cmpq $0x0, %rax
je 0xba212
jmp 0xba194
leaq 0x150(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x62fb0
movb %dl, 0x27(%rsp)
movq %rax, 0x28(%rsp)
jmp 0xba232
movb 0x27(%rsp), %al
movq 0x28(%rsp), %rcx
movq %rcx, 0xe8(%rsp)
movb %al, 0xf0(%rsp)
movq 0xf8(%rsp), %rdi
callq 0x62710
movq %rax, 0x18(%rsp)
jmp 0xba25e
movq 0x18(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x62720
movq %rax, 0xd8(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x62750
movq %rax, 0xd0(%rsp)
leaq 0xd8(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x62780
testb $0x1, %al
jne 0xba2b0
jmp 0xba2f0
leaq 0xd8(%rsp), %rdi
callq 0x627a0
movq (%rax), %rax
movq %rax, 0xc8(%rsp)
leaq 0x188(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0xbd7f0
jmp 0xba2df
jmp 0xba2e1
leaq 0xd8(%rsp), %rdi
callq 0x627f0
jmp 0xba295
jmp 0xba194
movq 0xa8(%rsp), %rax
addq $0x70, %rax
movq %rax, 0x10(%rsp)
leaq 0x150(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0xbd880
movq 0x8(%rsp), %rdi
movq %rax, 0xc0(%rsp)
callq 0xbd8b0
movq 0x10(%rsp), %rdi
movq %rax, 0xb8(%rsp)
movq 0xc0(%rsp), %rsi
movq 0xb8(%rsp), %rdx
callq 0xbd840
jmp 0xba34e
leaq 0x150(%rsp), %rdi
callq 0xbd6b0
leaq 0x140(%rsp), %rdi
callq 0xbd8e0
jmp 0xb9fff
movq 0xa8(%rsp), %rdi
addq $0xa8, %rdi
callq 0xbd910
movq 0xa8(%rsp), %rdi
movq 0x2b8(%rsp), %rsi
callq 0xba400
jmp 0xba398
leaq 0x150(%rsp), %rdi
callq 0x63010
leaq 0x188(%rsp), %rdi
callq 0xbd930
leaq 0x288(%rsp), %rdi
callq 0xbd940
leaq 0x2c8(%rsp), %rdi
callq 0x62570
jmp 0xb9d1e
leaq 0x288(%rsp), %rdi
callq 0xbd940
jmp 0xba3e8
addq $0x2e8, %rsp            # imm = 0x2E8
retq
movq 0x278(%rsp), %rdi
callq 0x8670
nopw %cs:(%rax,%rax)