// File: luooofan[P]hblzbd_compiler/src/Pass/arm_liveness_analysis.cpp
// Function: ArmLivenessAnalysis::Run4Func(ArmFunction*)
void ArmLivenessAnalysis::Run4Func(ArmFunction *f) {
  for (auto bb : f->bb_list_) {
    // NOTE: 发生实际溢出时会重新分析 需要先清空
    bb->livein_.clear();
    bb->liveout_.clear();
    bb->def_.clear();
    bb->use_.clear();
    // 对于每一条指令 取def和use并记录到basicblock中 加快数据流分析
    for (auto inst : bb->inst_list_) {
      auto [def, use] = GetDefUse(inst);
      for (auto &u : use) {
        // liveuse not use. if in def, not liveuse
        if (bb->def_.find(u) == bb->def_.end()) {
          bb->use_.insert(u);
        }
      }
      for (auto &d : def) {
        if (bb->use_.find(d) == bb->use_.end()) {
          bb->def_.insert(d);
        }
      }
    }
    // liveuse是入口活跃的那些use
    // def是非入口活跃use的那些def
    bb->livein_ = bb->use_;
  }

  // 为每一个basicblock计算livein和liveout
  bool changed = true;
  while (changed) {
    changed = false;
    for (auto bb : f->bb_list_) {
      std::unordered_set<RegId> new_out;
      // out[s]=U(succ:i)in[i]
      // 对每一个后继基本块
      // std::cout<<bb->succ_.size()<<std::endl;
      for (auto succ : bb->succ_) {
        //   if(succ){
        new_out.insert(succ->livein_.begin(), succ->livein_.end());
        //   }
      }

      if (new_out != bb->liveout_) {
        // 还未到达不动点
        changed = true;
        bb->liveout_ = new_out;
        // in[s]=use[s]U(out[s]-def[s]) 可增量添加
        for (auto s : bb->liveout_) {
          if (bb->def_.find(s) == bb->def_.end()) {
            bb->livein_.insert(s);  // 重复元素插入无副作用
          }
        }
      }
    }  // for every bb
  }    // while end}
}

// Assembly:
subq $0x238, %rsp            # imm = 0x238
movq %rdi, 0x230(%rsp)
movq 0x230(%rsp), %rax
addq $0x38, %rax
movq %rax, 0x228(%rsp)
movq 0x228(%rsp), %rdi
callq 0x10bd0
movq %rax, 0x220(%rsp)
movq 0x228(%rsp), %rdi
callq 0x10c00
movq %rax, 0x218(%rsp)
leaq 0x220(%rsp), %rdi
leaq 0x218(%rsp), %rsi
callq 0x10c30
testb $0x1, %al
jne 0x7c88b
jmp 0x7cc64
leaq 0x220(%rsp), %rdi
callq 0x10c70
movq (%rax), %rax
movq %rax, 0x210(%rsp)
movq 0x210(%rsp), %rdi
addq $0xe8, %rdi
callq 0x7d2d0
movq 0x210(%rsp), %rdi
addq $0x120, %rdi            # imm = 0x120
callq 0x7d2d0
movq 0x210(%rsp), %rdi
addq $0x78, %rdi
callq 0x7d2d0
movq 0x210(%rsp), %rdi
addq $0xb0, %rdi
callq 0x7d2d0
movq 0x210(%rsp), %rax
addq $0x30, %rax
movq %rax, 0x208(%rsp)
movq 0x208(%rsp), %rdi
callq 0xcaa0
movq %rax, 0x200(%rsp)
movq 0x208(%rsp), %rdi
callq 0xcad0
movq %rax, 0x1f8(%rsp)
leaq 0x200(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0xcb00
testb $0x1, %al
jne 0x7c94c
jmp 0x7cc2f
leaq 0x200(%rsp), %rdi
callq 0xf5c0
movq (%rax), %rax
movq %rax, 0x1f0(%rsp)
movq 0x1f0(%rsp), %rsi
leaq 0x1c0(%rsp), %rdi
callq 0x7b400
leaq 0x1c0(%rsp), %rdi
callq 0x70780
movq %rax, 0x1b8(%rsp)
leaq 0x1c0(%rsp), %rdi
callq 0x70790
movq %rax, 0x1b0(%rsp)
movq 0x1b0(%rsp), %rax
movq %rax, 0x1a8(%rsp)
movq 0x1a8(%rsp), %rdi
callq 0x1fc30
movq %rax, 0x1a0(%rsp)
movq 0x1a8(%rsp), %rdi
callq 0x1f470
movq %rax, 0x198(%rsp)
leaq 0x1a0(%rsp), %rdi
leaq 0x198(%rsp), %rsi
callq 0x37210
testb $0x1, %al
jne 0x7c9fb
jmp 0x7caec
leaq 0x1a0(%rsp), %rdi
callq 0x37250
movq %rax, 0x190(%rsp)
movq 0x210(%rsp), %rdi
addq $0x78, %rdi
movq 0x190(%rsp), %rsi
callq 0x6ee40
movq %rax, 0x48(%rsp)
jmp 0x7ca30
movq 0x48(%rsp), %rax
movq %rax, 0x188(%rsp)
movq 0x210(%rsp), %rdi
addq $0x78, %rdi
callq 0x6ecc0
movq %rax, 0x170(%rsp)
leaq 0x188(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x6ee20
testb $0x1, %al
jne 0x7ca71
jmp 0x7cad8
movq 0x210(%rsp), %rdi
addq $0xb0, %rdi
movq 0x190(%rsp), %rsi
callq 0x70850
movb %dl, 0x3f(%rsp)
movq %rax, 0x40(%rsp)
jmp 0x7ca98
movb 0x3f(%rsp), %al
movq 0x40(%rsp), %rcx
movq %rcx, 0x160(%rsp)
movb %al, 0x168(%rsp)
jmp 0x7cad8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
leaq 0x1c0(%rsp), %rdi
callq 0x708a0
jmp 0x7cf92
jmp 0x7cada
leaq 0x1a0(%rsp), %rdi
callq 0x37260
jmp 0x7c9dd
movq 0x1b8(%rsp), %rax
movq %rax, 0x158(%rsp)
movq 0x158(%rsp), %rdi
callq 0x1fc30
movq %rax, 0x150(%rsp)
movq 0x158(%rsp), %rdi
callq 0x1f470
movq %rax, 0x148(%rsp)
leaq 0x150(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x37210
testb $0x1, %al
jne 0x7cb44
jmp 0x7cc10
leaq 0x150(%rsp), %rdi
callq 0x37250
movq %rax, 0x140(%rsp)
movq 0x210(%rsp), %rdi
addq $0xb0, %rdi
movq 0x140(%rsp), %rsi
callq 0x6ee40
movq %rax, 0x30(%rsp)
jmp 0x7cb7c
movq 0x30(%rsp), %rax
movq %rax, 0x138(%rsp)
movq 0x210(%rsp), %rdi
addq $0xb0, %rdi
callq 0x6ecc0
movq %rax, 0x130(%rsp)
leaq 0x138(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0x6ee20
testb $0x1, %al
jne 0x7cbc0
jmp 0x7cbfc
movq 0x210(%rsp), %rdi
addq $0x78, %rdi
movq 0x140(%rsp), %rsi
callq 0x70850
movb %dl, 0x27(%rsp)
movq %rax, 0x28(%rsp)
jmp 0x7cbe4
movb 0x27(%rsp), %al
movq 0x28(%rsp), %rcx
movq %rcx, 0x120(%rsp)
movb %al, 0x128(%rsp)
jmp 0x7cbfe
leaq 0x150(%rsp), %rdi
callq 0x37260
jmp 0x7cb26
leaq 0x1c0(%rsp), %rdi
callq 0x708a0
leaq 0x200(%rsp), %rdi
callq 0xf8f0
jmp 0x7c92e
movq 0x210(%rsp), %rsi
addq $0xb0, %rsi
movq 0x210(%rsp), %rdi
addq $0xe8, %rdi
callq 0x7d2e0
leaq 0x220(%rsp), %rdi
callq 0x10c80
jmp 0x7c86d
movb $0x1, 0x11f(%rsp)
testb $0x1, 0x11f(%rsp)
je 0x7cf8a
movb $0x0, 0x11f(%rsp)
movq 0x230(%rsp), %rax
addq $0x38, %rax
movq %rax, 0x110(%rsp)
movq 0x110(%rsp), %rdi
callq 0x10bd0
movq %rax, 0x108(%rsp)
movq 0x110(%rsp), %rdi
callq 0x10c00
movq %rax, 0x100(%rsp)
leaq 0x108(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x10c30
testb $0x1, %al
jne 0x7ccde
jmp 0x7cf85
leaq 0x108(%rsp), %rdi
callq 0x10c70
movq (%rax), %rax
movq %rax, 0xf8(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x6ef10
movq 0xf8(%rsp), %rax
addq $0x60, %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x10bd0
movq %rax, 0xb0(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x10c00
movq %rax, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x10c30
testb $0x1, %al
jne 0x7cd5f
jmp 0x7ce08
leaq 0xb0(%rsp), %rdi
callq 0x10c70
movq (%rax), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
addq $0xe8, %rdi
callq 0x6ec90
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rdi
addq $0xe8, %rdi
callq 0x6ecc0
movq %rax, 0x90(%rsp)
movq 0x98(%rsp), %rsi
movq 0x90(%rsp), %rdx
leaq 0xc0(%rsp), %rdi
callq 0x7d310
jmp 0x7cdce
jmp 0x7cdd0
leaq 0xb0(%rsp), %rdi
callq 0x10c80
jmp 0x7cd41
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x6eeb0
jmp 0x7cf92
movq 0xf8(%rsp), %rsi
addq $0x120, %rsi            # imm = 0x120
leaq 0xc0(%rsp), %rdi
callq 0x7d350
movb %al, 0x26(%rsp)
jmp 0x7ce2a
movb 0x26(%rsp), %al
testb $0x1, %al
jne 0x7ce37
jmp 0x7cf66
movb $0x1, 0x11f(%rsp)
movq 0xf8(%rsp), %rdi
addq $0x120, %rdi            # imm = 0x120
leaq 0xc0(%rsp), %rsi
callq 0x7d2e0
jmp 0x7ce5d
movq 0xf8(%rsp), %rax
addq $0x120, %rax            # imm = 0x120
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
callq 0x6ec90
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
callq 0x6ecc0
movq %rax, 0x78(%rsp)
leaq 0x80(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x6ecf0
testb $0x1, %al
jne 0x7ceb5
jmp 0x7cf64
leaq 0x80(%rsp), %rdi
callq 0x6ed10
movl (%rax), %eax
movl %eax, 0x74(%rsp)
movq 0xf8(%rsp), %rdi
addq $0x78, %rdi
leaq 0x74(%rsp), %rsi
callq 0x6ee40
movq %rax, 0x18(%rsp)
jmp 0x7cee5
movq 0x18(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0xf8(%rsp), %rdi
addq $0x78, %rdi
callq 0x6ecc0
movq %rax, 0x60(%rsp)
leaq 0x68(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x6ee20
testb $0x1, %al
jne 0x7cf1a
jmp 0x7cf50
movq 0xf8(%rsp), %rdi
addq $0xe8, %rdi
leaq 0x74(%rsp), %rsi
callq 0x70850
movb %dl, 0xf(%rsp)
movq %rax, 0x10(%rsp)
jmp 0x7cf3e
movb 0xf(%rsp), %al
movq 0x10(%rsp), %rcx
movq %rcx, 0x50(%rsp)
movb %al, 0x58(%rsp)
jmp 0x7cf52
leaq 0x80(%rsp), %rdi
callq 0x6ed30
jmp 0x7ce9a
jmp 0x7cf66
leaq 0xc0(%rsp), %rdi
callq 0x6eeb0
leaq 0x108(%rsp), %rdi
callq 0x10c80
jmp 0x7ccc0
jmp 0x7cc6c
addq $0x238, %rsp            # imm = 0x238
retq
movq 0x180(%rsp), %rdi
callq 0x8670
nop