// File: luooofan[P]hblzbd_compiler/src/Pass/convert_ssa.cpp
// Function: ConvertSSA::InsertPhiIR(IRFunction*)
void ConvertSSA::InsertPhiIR(IRFunction* f) {
#ifdef DEBUG_CONVERT_SSA_PROCESS
  std::cout << "insert phi" << std::endl;
#endif
  std::unordered_map<std::string, std::unordered_set<IRBasicBlock*>> defsites;  // 变量被定值的基本块集合
  std::unordered_map<IRBasicBlock*, std::unordered_set<std::string>> phi_vars;  // 一个基本块内拥有phi函数的变量
  // compute def_use without array
  IRLivenessAnalysis::GetDefUse4Func(f, false);
  // fill defsites
  for (auto bb : f->bb_list_) {
    for (auto& def : bb->def_) {
      defsites[def].insert(bb);
    }
  }
  IRLivenessAnalysis::Run4Func(f);  // 用于插入phi node的时候判断是否活跃决定是否插入
  for (auto& [var, defbbs] : defsites) {
    while (!defbbs.empty()) {
      auto bb = *defbbs.begin();
#ifdef DEBUG_CONVERT_SSA_PROCESS
      std::cout << "var:" << var << "在这些bb中def:" << std::endl;
      std::cout << bb->IndexInFunc() << std::endl;
#endif
      defbbs.erase(defbbs.begin());
      for (auto df : bb->df_) {  // 对于变量定值所在bb的每一个df都要加一个phi函数
        // NOTE: 如果var并不入口活跃就不用加入phi函数
        if (df->livein_.find(var) == df->livein_.end()) continue;
        if (phi_vars.find(df) == phi_vars.end() || phi_vars[df].find(var) == phi_vars[df].end()) {
          phi_vars[df].insert(var);
          auto&& res = CompName2Opn(var);
          // NOTE: phi结点的scope id可能并不正确
          auto ir_list_it = df->ir_list_.begin();
          while (ir_list_it != df->ir_list_.end() && (*ir_list_it)->op_ == IR::OpKind::LABEL) ++ir_list_it;
          df->ir_list_.insert(ir_list_it, new IR{IR::OpKind::PHI, res, static_cast<int>(df->pred_.size())});
          if (df->def_.find(var) == df->def_.end()) {
            df->def_.insert(var);
            defbbs.insert(df);
          }
        }
      }  // end of df for
    }    // end of defbbs while
#ifdef DEBUG_CONVERT_SSA_PROCESS
    std::cout << "end." << std::endl;
#endif
  }  // end of defsites for
}

// Assembly:
subq $0x328, %rsp            # imm = 0x328
movq %rdi, 0x320(%rsp)
movq %rsi, 0x318(%rsp)
leaq 0x2e0(%rsp), %rdi
callq 0x8f690
leaq 0x2a8(%rsp), %rdi
callq 0x8f6a0
movq 0x318(%rsp), %rdi
xorl %esi, %esi
callq 0xc92a0
jmp 0x854e2
movq 0x318(%rsp), %rax
addq $0x30, %rax
movq %rax, 0x290(%rsp)
movq 0x290(%rsp), %rdi
callq 0x1cc40
movq %rax, 0x288(%rsp)
movq 0x290(%rsp), %rdi
callq 0x1cac0
movq %rax, 0x280(%rsp)
leaq 0x288(%rsp), %rdi
leaq 0x280(%rsp), %rsi
callq 0x492e0
testb $0x1, %al
jne 0x8553e
jmp 0x85669
leaq 0x288(%rsp), %rdi
callq 0x49320
movq (%rax), %rax
movq %rax, 0x278(%rsp)
movq 0x278(%rsp), %rax
addq $0x58, %rax
movq %rax, 0x270(%rsp)
movq 0x270(%rsp), %rdi
callq 0x8f6b0
movq %rax, 0x268(%rsp)
movq 0x270(%rsp), %rdi
callq 0x8f6e0
movq %rax, 0x260(%rsp)
leaq 0x268(%rsp), %rdi
leaq 0x260(%rsp), %rsi
callq 0x8f710
testb $0x1, %al
jne 0x855b2
jmp 0x85655
leaq 0x268(%rsp), %rdi
callq 0x8f730
movq %rax, 0x258(%rsp)
movq 0x258(%rsp), %rsi
leaq 0x2e0(%rsp), %rdi
callq 0x8f750
movq %rax, 0xa8(%rsp)
jmp 0x855e6
movq 0xa8(%rsp), %rdi
leaq 0x278(%rsp), %rsi
callq 0x8f780
movb %dl, 0x9f(%rsp)
movq %rax, 0xa0(%rsp)
jmp 0x8560c
movb 0x9f(%rsp), %al
movq 0xa0(%rsp), %rcx
movq %rcx, 0x248(%rsp)
movb %al, 0x250(%rsp)
leaq 0x268(%rsp), %rdi
callq 0x8f7d0
jmp 0x85594
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
jmp 0x85d06
jmp 0x85657
leaq 0x288(%rsp), %rdi
callq 0x49330
jmp 0x85520
movq 0x318(%rsp), %rdi
callq 0xc95c0
jmp 0x85678
leaq 0x2e0(%rsp), %rax
movq %rax, 0x240(%rsp)
movq 0x240(%rsp), %rdi
callq 0x8f800
movq %rax, 0x238(%rsp)
movq 0x240(%rsp), %rdi
callq 0x8f830
movq %rax, 0x230(%rsp)
leaq 0x238(%rsp), %rdi
leaq 0x230(%rsp), %rsi
callq 0x8f860
testb $0x1, %al
jne 0x856d0
jmp 0x85ce4
leaq 0x238(%rsp), %rdi
callq 0x8f880
movq %rax, 0x228(%rsp)
movq 0x228(%rsp), %rdi
callq 0x8f8a0
movq %rax, 0x220(%rsp)
movq 0x228(%rsp), %rdi
callq 0x8f8b0
movq %rax, 0x218(%rsp)
movq 0x218(%rsp), %rdi
callq 0x8f8c0
xorb $-0x1, %al
testb $0x1, %al
jne 0x85727
jmp 0x85cd0
movq 0x218(%rsp), %rdi
callq 0x8d590
movq %rax, 0x208(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x8d610
movq (%rax), %rax
movq %rax, 0x210(%rsp)
movq 0x218(%rsp), %rdi
movq %rdi, 0x88(%rsp)
callq 0x8d590
movq 0x88(%rsp), %rdi
movq %rax, 0x200(%rsp)
movq 0x200(%rsp), %rsi
callq 0x8f8e0
movq %rax, 0x90(%rsp)
jmp 0x85790
movq 0x90(%rsp), %rax
movq %rax, 0x1f8(%rsp)
movq 0x210(%rsp), %rax
addq $0x270, %rax            # imm = 0x270
movq %rax, 0x1f0(%rsp)
movq 0x1f0(%rsp), %rdi
callq 0x8d590
movq %rax, 0x1e8(%rsp)
movq 0x1f0(%rsp), %rdi
callq 0x8d5c0
movq %rax, 0x1e0(%rsp)
leaq 0x1e8(%rsp), %rdi
leaq 0x1e0(%rsp), %rsi
callq 0x8d5f0
testb $0x1, %al
jne 0x857fe
jmp 0x85ccb
leaq 0x1e8(%rsp), %rdi
callq 0x8d610
movq (%rax), %rax
movq %rax, 0x1d8(%rsp)
movq 0x1d8(%rsp), %rdi
addq $0xc8, %rdi
movq 0x220(%rsp), %rsi
callq 0x8f940
movq %rax, 0x80(%rsp)
jmp 0x8583c
movq 0x80(%rsp), %rax
movq %rax, 0x1d0(%rsp)
movq 0x1d8(%rsp), %rdi
addq $0xc8, %rdi
callq 0x8f6e0
movq %rax, 0x1c8(%rsp)
leaq 0x1d0(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
callq 0x8f920
testb $0x1, %al
jne 0x85883
jmp 0x85888
jmp 0x85cb9
leaq 0x2a8(%rsp), %rdi
leaq 0x1d8(%rsp), %rsi
callq 0x8f990
movq %rax, 0x78(%rsp)
jmp 0x858a4
movq 0x78(%rsp), %rax
movq %rax, 0x1c0(%rsp)
leaq 0x2a8(%rsp), %rdi
callq 0x8f9c0
movq %rax, 0x1b8(%rsp)
leaq 0x1c0(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
callq 0x8f970
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0x77(%rsp)
jne 0x85975
leaq 0x2a8(%rsp), %rdi
leaq 0x1d8(%rsp), %rsi
callq 0x8f9f0
movq %rax, 0x68(%rsp)
jmp 0x85908
movq 0x68(%rsp), %rdi
movq 0x220(%rsp), %rsi
callq 0x8f940
movq %rax, 0x60(%rsp)
jmp 0x85921
movq 0x60(%rsp), %rax
movq %rax, 0x1b0(%rsp)
leaq 0x2a8(%rsp), %rdi
leaq 0x1d8(%rsp), %rsi
callq 0x8f9f0
movq %rax, 0x58(%rsp)
jmp 0x8594a
movq 0x58(%rsp), %rdi
callq 0x8f6e0
movq %rax, 0x1a8(%rsp)
leaq 0x1b0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x8f920
movb %al, 0x77(%rsp)
movb 0x77(%rsp), %al
testb $0x1, %al
jne 0x85982
jmp 0x85cb7
leaq 0x2a8(%rsp), %rdi
leaq 0x1d8(%rsp), %rsi
callq 0x8f9f0
movq %rax, 0x50(%rsp)
jmp 0x8599e
movq 0x50(%rsp), %rdi
movq 0x220(%rsp), %rsi
callq 0x8fa20
movb %dl, 0x47(%rsp)
movq %rax, 0x48(%rsp)
jmp 0x859bb
movb 0x47(%rsp), %al
movq 0x48(%rsp), %rcx
movq %rcx, 0x198(%rsp)
movb %al, 0x1a0(%rsp)
movq 0x220(%rsp), %rsi
leaq 0x150(%rsp), %rdi
callq 0x8cac0
jmp 0x859ea
leaq 0x150(%rsp), %rax
movq %rax, 0x190(%rsp)
movq 0x1d8(%rsp), %rdi
addq $0x8, %rdi
callq 0x1b070
movq %rax, 0x148(%rsp)
movq 0x1d8(%rsp), %rdi
addq $0x8, %rdi
callq 0x1aeb0
movq %rax, 0x140(%rsp)
leaq 0x148(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x493c0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0x46(%rsp)
jne 0x85a50
jmp 0x85a6a
leaq 0x148(%rsp), %rdi
callq 0x1b4d0
movq (%rax), %rax
cmpl $0x7, (%rax)
sete %al
movb %al, 0x46(%rsp)
movb 0x46(%rsp), %al
testb $0x1, %al
jne 0x85a74
jmp 0x85a83
leaq 0x148(%rsp), %rdi
callq 0x49460
jmp 0x85a13
movq 0x1d8(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x30(%rsp)
leaq 0x138(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x8d790
movl $0xe0, %edi
callq 0x8340
movq %rax, 0x38(%rsp)
jmp 0x85aba
movb $0x1, 0xef(%rsp)
movq 0x190(%rsp), %rsi
leaq 0xf0(%rsp), %rdi
callq 0x43130
jmp 0x85ad9
movq 0x1d8(%rsp), %rdi
addq $0x28, %rdi
callq 0x1cd80
movq 0x38(%rsp), %rdi
movl %eax, %ecx
movl $0x15, %esi
leaq 0xf0(%rsp), %rdx
callq 0x8fab0
jmp 0x85b05
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rax
movb $0x0, 0xef(%rsp)
movq %rax, 0x130(%rsp)
movq 0x138(%rsp), %rsi
leaq 0x130(%rsp), %rdx
callq 0x8fa70
movq %rax, 0x28(%rsp)
jmp 0x85b3b
movq 0x28(%rsp), %rax
movq %rax, 0xe0(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x1f210
movq 0x1d8(%rsp), %rdi
addq $0x58, %rdi
movq 0x220(%rsp), %rsi
callq 0x8f940
movq %rax, 0x20(%rsp)
jmp 0x85b75
movq 0x20(%rsp), %rax
movq %rax, 0xd8(%rsp)
movq 0x1d8(%rsp), %rdi
addq $0x58, %rdi
callq 0x8f6e0
movq %rax, 0xd0(%rsp)
leaq 0xd8(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x8f920
testb $0x1, %al
jne 0x85bb9
jmp 0x85c99
movq 0x1d8(%rsp), %rdi
addq $0x58, %rdi
movq 0x220(%rsp), %rsi
callq 0x8fa20
movb %dl, 0x17(%rsp)
movq %rax, 0x18(%rsp)
jmp 0x85bdd
movb 0x17(%rsp), %al
movq 0x18(%rsp), %rcx
movq %rcx, 0xc0(%rsp)
movb %al, 0xc8(%rsp)
movq 0x218(%rsp), %rdi
leaq 0x1d8(%rsp), %rsi
callq 0x8f780
movb %dl, 0x7(%rsp)
movq %rax, 0x8(%rsp)
jmp 0x85c15
movb 0x7(%rsp), %al
movq 0x8(%rsp), %rcx
movq %rcx, 0xb0(%rsp)
movb %al, 0xb8(%rsp)
jmp 0x85c99
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
jmp 0x85ca8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
jmp 0x85c7c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x1f210
testb $0x1, 0xef(%rsp)
jne 0x85c88
jmp 0x85c97
movq 0x38(%rsp), %rdi
movl $0xe0, %esi
callq 0x8350
jmp 0x85ca8
leaq 0x150(%rsp), %rdi
callq 0x1f210
jmp 0x85cb7
leaq 0x150(%rsp), %rdi
callq 0x1f210
jmp 0x85d06
jmp 0x85cb9
leaq 0x1e8(%rsp), %rdi
callq 0x8d670
jmp 0x857e0
jmp 0x8570f
jmp 0x85cd2
leaq 0x238(%rsp), %rdi
callq 0x8fbb0
jmp 0x856b2
leaq 0x2a8(%rsp), %rdi
callq 0x8fbe0
leaq 0x2e0(%rsp), %rdi
callq 0x8fbf0
addq $0x328, %rsp            # imm = 0x328
retq
leaq 0x2a8(%rsp), %rdi
callq 0x8fbe0
leaq 0x2e0(%rsp), %rdi
callq 0x8fbf0
movq 0x2a0(%rsp), %rdi
callq 0x8670
nopl (%rax)