// File: luooofan[P]hblzbd_compiler/src/Pass/convert_ssa.cpp
// Function: ConvertSSA::ConstructSSA(IRModule*)
SSAModule* ConvertSSA::ConstructSSA(IRModule* module) {
  // 由ir module直接构建ssa module 构建的过程中把ir中的label语句删掉 转化成了基本块的label
  // NOTE: 可能会出现一些空的bb 有些基本块是unnamed
  SSAModule* ssamodule = new SSAModule(module->global_scope_, module->name_);  // FIXME: terrible design
  std::unordered_map<IRFunction*, SSAFunction*> func_map;

  // process all global variable
  this->ProcessGlobalVariable(module, ssamodule);
  this->AddBuiltInFunction(ssamodule);

  // for every ir func
  for (auto func : module->func_list_) {
#ifdef DEBUG_CONSTRUCT_SSA_PROCESS
    std::cout << "--Process Func:" << func->name_ << std::endl;
#endif

    SSAFunction* ssafunc = new SSAFunction(func->name_, ssamodule);
    func_map.insert({func, ssafunc});
    glob_map[func->name_] = new FunctionValue(func->name_, ssafunc);

    work_map.clear();
    std::unordered_map<IRBasicBlock*, SSABasicBlock*> bb_map;
    this->GenerateSSABasicBlocks(func, ssafunc, bb_map);

    // for every ir basicblock
    // NOTE: 需要保证转化SSA时dom tree未发生变化 每次新填充到glob map和work map中的不能删除 为了之后填充phi结点用
    std::deque<IRBasicBlock*> q;
    if (!func->bb_list_.empty()) q.push_back(func->bb_list_.front());
    while (!q.empty()) {
      auto bb = q.front();
      q.pop_front();
      ConstructSSA4BB(bb, ssafunc, bb_map);
      for (auto dom : bb->doms_) {
        q.push_back(dom);
      }
    }

    // for every ir basicblock
    // for (auto bb : func->bb_list_) {
    //   ConstructSSA4BB(bb, ssafunc, bb_map);
    // }

    FillPhiInst(func, ssafunc, bb_map);
  }  // end of ir function loop

  return ssamodule;
}

// Assembly:
subq $0x1d8, %rsp            # imm = 0x1D8
movq %rdi, 0x1d0(%rsp)
movq %rsi, 0x1c8(%rsp)
movq 0x1d0(%rsp), %rax
movq %rax, 0x48(%rsp)
movl $0x98, %edi
callq 0x8340
movq %rax, 0x50(%rsp)
movb $0x1, 0x193(%rsp)
movq 0x1c8(%rsp), %rsi
movq 0x40(%rsi), %rax
movq %rax, 0x58(%rsp)
addq $0x8, %rsi
leaq 0x1a0(%rsp), %rdi
callq 0x81a0
jmp 0x86e9f
movq 0x58(%rsp), %rsi
movq 0x50(%rsp), %rdi
leaq 0x1a0(%rsp), %rdx
callq 0x8ee90
jmp 0x86eb8
movb $0x0, 0x193(%rsp)
leaq 0x1a0(%rsp), %rdi
callq 0x8728
movq 0x50(%rsp), %rax
movq %rax, 0x1c0(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x8ef70
movq 0x48(%rsp), %rdi
movq 0x1c8(%rsp), %rsi
movq 0x1c0(%rsp), %rdx
callq 0x87e90
jmp 0x86f03
movq 0x48(%rsp), %rdi
movq 0x1c0(%rsp), %rsi
callq 0x88030
jmp 0x86f17
movq 0x1c8(%rsp), %rax
addq $0x28, %rax
movq %rax, 0x150(%rsp)
movq 0x150(%rsp), %rdi
callq 0x1d3c0
movq %rax, 0x148(%rsp)
movq 0x150(%rsp), %rdi
callq 0x1d240
movq %rax, 0x140(%rsp)
leaq 0x148(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x49210
testb $0x1, %al
jne 0x86f73
jmp 0x87358
leaq 0x148(%rsp), %rdi
callq 0x49250
movq (%rax), %rax
movq %rax, 0x138(%rsp)
movl $0xb8, %edi
callq 0x8340
movq %rax, 0x40(%rsp)
jmp 0x86f9c
movq 0x40(%rsp), %rdi
movq 0x138(%rsp), %rsi
addq $0x8, %rsi
movq 0x1c0(%rsp), %rdx
callq 0x8ef80
jmp 0x86fbc
movq 0x40(%rsp), %rax
movq %rax, 0x130(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x138(%rsp), %rsi
leaq 0x130(%rsp), %rdx
callq 0x8f0a0
jmp 0x86fe8
leaq 0x158(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x8f050
movb %dl, 0x37(%rsp)
movq %rax, 0x38(%rsp)
jmp 0x87008
movb 0x37(%rsp), %al
movq 0x38(%rsp), %rcx
movq %rcx, 0x110(%rsp)
movb %al, 0x118(%rsp)
movl $0x68, %edi
callq 0x8340
movq %rax, 0x28(%rsp)
jmp 0x87031
movq 0x28(%rsp), %rdi
movq 0x138(%rsp), %rsi
addq $0x8, %rsi
movq 0x130(%rsp), %rdx
callq 0x5c640
jmp 0x87051
movq 0x48(%rsp), %rdi
addq $0xe0, %rdi
movq 0x138(%rsp), %rsi
addq $0x8, %rsi
callq 0x8cd60
movq %rax, 0x20(%rsp)
jmp 0x87075
movq 0x48(%rsp), %rdi
movq 0x20(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rcx, (%rax)
addq $0xa8, %rdi
callq 0x8f0d0
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x8f0e0
movq 0x48(%rsp), %rdi
movq 0x18(%rsp), %rcx
movq 0x138(%rsp), %rsi
movq 0x130(%rsp), %rdx
callq 0x899f0
jmp 0x870c6
leaq 0x88(%rsp), %rdi
callq 0x8f0f0
jmp 0x870d5
movq 0x138(%rsp), %rdi
addq $0x30, %rdi
callq 0x8f100
testb $0x1, %al
jne 0x87215
movq 0x138(%rsp), %rdi
addq $0x30, %rdi
callq 0x8cc90
movq %rax, %rsi
leaq 0x88(%rsp), %rdi
callq 0x8f150
jmp 0x87111
jmp 0x87215
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
jmp 0x8714d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
leaq 0x1a0(%rsp), %rdi
callq 0x8728
testb $0x1, 0x193(%rsp)
jne 0x87159
jmp 0x87168
movq 0x50(%rsp), %rdi
movl $0x98, %esi
callq 0x8350
jmp 0x8738c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
jmp 0x8737f
movq 0x40(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
movl $0xb8, %esi
callq 0x8350
jmp 0x8737f
movq 0x28(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
movl $0x68, %esi
callq 0x8350
jmp 0x8737f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
jmp 0x87349
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x198(%rsp)
movl %eax, 0x194(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x8f270
jmp 0x87349
jmp 0x87217
leaq 0x88(%rsp), %rdi
callq 0x8f1b0
xorb $-0x1, %al
testb $0x1, %al
jne 0x8722f
jmp 0x872f9
leaq 0x88(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x8f1d0
movq 0x10(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x80(%rsp)
callq 0x8f200
movq 0x48(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x130(%rsp), %rdx
leaq 0xd8(%rsp), %rcx
callq 0x8a5d0
jmp 0x8727a
movq 0x80(%rsp), %rax
addq $0x258, %rax            # imm = 0x258
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rdi
callq 0x1cc40
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rdi
callq 0x1cac0
movq %rax, 0x68(%rsp)
leaq 0x70(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x492e0
testb $0x1, %al
jne 0x872c0
jmp 0x872f4
leaq 0x70(%rsp), %rdi
callq 0x49320
movq (%rax), %rax
movq %rax, 0x60(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x8f150
jmp 0x872e6
jmp 0x872e8
leaq 0x70(%rsp), %rdi
callq 0x49330
jmp 0x872ab
jmp 0x87217
movq 0x48(%rsp), %rdi
movq 0x138(%rsp), %rsi
movq 0x130(%rsp), %rdx
leaq 0xd8(%rsp), %rcx
callq 0x8c790
jmp 0x8731d
leaq 0x88(%rsp), %rdi
callq 0x8f270
leaq 0xd8(%rsp), %rdi
callq 0x8f2e0
leaq 0x148(%rsp), %rdi
callq 0x49260
jmp 0x86f55
leaq 0xd8(%rsp), %rdi
callq 0x8f2e0
jmp 0x8737f
movq 0x1c0(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x8f2f0
movq 0x8(%rsp), %rax
addq $0x1d8, %rsp            # imm = 0x1D8
retq
leaq 0x158(%rsp), %rdi
callq 0x8f2f0
movq 0x198(%rsp), %rdi
callq 0x8670
nopl (%rax)