// File: /workspace/github_cpp_makefile_star2_O3/luooofan[P]hblzbd_compiler/src/Pass/arm_liveness_analysis.cpp
// Function: GetDefUse(arm::Instruction*)
std::pair<std::vector<RegId>, std::vector<RegId>> GetDefUse(Instruction *inst) {
  std::vector<RegId> def;
  std::vector<RegId> use;

  auto process_op2 = [&use](Operand2 *op2) {
    if (nullptr == op2) return;
    if (op2->is_imm_) return;
    use.push_back(op2->reg_->reg_id_);
    if (nullptr != op2->shift_ && !op2->shift_->is_imm_) {
      use.push_back(op2->shift_->shift_reg_->reg_id_);
    }
    return;
  };

  if (auto src_inst = dynamic_cast<BinaryInst *>(inst)) {
    if (nullptr != src_inst->rd_) {
      def.push_back(src_inst->rd_->reg_id_);
    }
    use.push_back(src_inst->rn_->reg_id_);
    process_op2(src_inst->op2_);
  } else if (auto src_inst = dynamic_cast<Move *>(inst)) {
    def.push_back(src_inst->rd_->reg_id_);
    process_op2(src_inst->op2_);
  } else if (auto src_inst = dynamic_cast<Branch *>(inst)) {
    // call可先视为对前面已经定义的参数寄存器的使用 再视作对调用者保护的寄存器的定义 不管之后这些寄存器有没有被使用
    // caller save regs: r0-r3, lr, ip
    // ret可视为对r0和lr的使用 但需要保证armcode是正确的 i.e. 如果前面有bl xxx指令的话 后面不能用bx lr指令返回
    // 如果b后面是个函数label就是call 如果b后面是lr就是ret
    auto &label = src_inst->label_;
    if (src_inst->IsRet()) {  // bx lr
      use.push_back(static_cast<RegId>(ArmReg::r0));
      use.push_back(static_cast<RegId>(ArmReg::lr));
    } else if (src_inst->IsCall()) {  // call
      int callee_param_num = ir::gFuncTable[label].shape_list_.size();
      for (RegId i = 0; i < std::min(callee_param_num, 4); ++i) {
        use.push_back(i);
      }
      for (RegId i = 0; i < 4; ++i) {
        def.push_back(i);
      }
      def.push_back(static_cast<RegId>(ArmReg::ip));
      def.push_back(static_cast<RegId>(ArmReg::lr));
    }
  } else if (auto src_inst = dynamic_cast<LdrStr *>(inst)) {
    if (src_inst->opkind_ == LdrStr::OpKind::LDR) {
      def.push_back(src_inst->rd_->reg_id_);
    } else {
      use.push_back(src_inst->rd_->reg_id_);
    }
    use.push_back(src_inst->rn_->reg_id_);
    process_op2(src_inst->offset_);
  } else if (auto src_inst = dynamic_cast<LdrPseudo *>(inst)) {
    def.push_back(src_inst->rd_->reg_id_);
  } else if (auto src_inst = dynamic_cast<PushPop *>(inst)) {
    if (src_inst->opkind_ == PushPop::OpKind::PUSH) {
      for (auto reg : src_inst->reg_list_) {
        use.push_back(reg->reg_id_);
      }
    } else {
      for (auto reg : src_inst->reg_list_) {
        if (reg->reg_id_ == static_cast<RegId>(ArmReg::pc)) {
          // 此时作为ret语句 视为对r0的使用以及对pc的定义
          use.push_back(static_cast<RegId>(ArmReg::r0));
        }
        def.push_back(reg->reg_id_);
      }
    }
  } else {  // 未实现其他指令
    MyAssert(0);
  }

  return {def, use};
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
xorl %eax, %eax
movq %rax, 0x40(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movq %rax, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
testq %rsi, %rsi
je 0x3bca4
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x51f8f(%rip), %rsi     # 0x8d5f8
leaq 0x51e68(%rip), %rdx     # 0x8d4d8
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3b6c9
movq %rax, %r15
movq 0x20(%rax), %rdx
testq %rdx, %rdx
je 0x3b742
addq $0x38, %rdx
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x129f6
movq 0x18(%rsp), %rsi
movq 0x28(%r15), %rdx
addq $0x38, %rdx
cmpq 0x20(%rsp), %rsi
je 0x3b74c
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3b756
leaq 0x51f28(%rip), %rsi     # 0x8d5f8
leaq 0x51e61(%rip), %rdx     # 0x8d538
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3b790
movq %rax, %r15
movq 0x18(%rax), %rdx
addq $0x38, %rdx
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x129f6
movq 0x20(%r15), %r14
testq %r14, %r14
je 0x3ba55
cmpb $0x0, (%r14)
jne 0x3ba55
movq 0x8(%r14), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3b9aa
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3b9b4
movq 0x28(%r15), %rdx
addq $0x38, %rdx
xorl %esi, %esi
leaq 0x10(%rsp), %rdi
callq 0x129f6
movq 0x30(%r15), %r14
testq %r14, %r14
je 0x3ba55
cmpb $0x0, (%r14)
jne 0x3ba55
movq 0x8(%r14), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3b7f3
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3b7fd
leaq 0x51e61(%rip), %rsi     # 0x8d5f8
leaq 0x51db2(%rip), %rdx     # 0x8d550
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3b83b
movq %rax, %r15
movq %rax, %rdi
callq 0xab90
testb %al, %al
je 0x3b8aa
movl $0x0, 0xc(%rsp)
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
cmpq %rax, %rsi
je 0x3ba20
movl $0x0, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3ba39
leaq 0x10(%rsp), %rdi
callq 0x129f6
movq 0x10(%r14), %rax
testq %rax, %rax
je 0x3ba55
cmpb $0x0, 0x4(%rax)
jne 0x3ba55
movq 0x10(%rax), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
jne 0x3b9e3
leaq 0x10(%rsp), %rdi
callq 0x129f6
jmp 0x3ba55
leaq 0x51db6(%rip), %rsi     # 0x8d5f8
leaq 0x51d67(%rip), %rdx     # 0x8d5b0
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3b9e9
movq %rax, %r15
movq 0x20(%rax), %rdx
addq $0x38, %rdx
cmpl $0x0, 0x14(%rax)
leaq 0x30(%rsp), %rax
leaq 0x10(%rsp), %rdi
cmoveq %rax, %rdi
xorl %esi, %esi
callq 0x129f6
movq 0x28(%r15), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bab8
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bac2
movq %r15, %rdi
callq 0xab5a
testb %al, %al
je 0x3ba55
addq $0x18, %r15
leaq 0x53ccb(%rip), %rdi     # 0x8f590
movq %r15, %rsi
callq 0x3ccd4
movq 0x10(%rax), %rcx
subq 0x8(%rax), %rcx
shrq $0x3, %rcx
imull $0xaaaaaaab, %ecx, %eax # imm = 0xAAAAAAAB
cmpl $0x4, %eax
movl $0x4, %ebp
cmovll %eax, %ebp
movl $0x0, 0xc(%rsp)
testl %eax, %eax
jle 0x3b934
xorl %eax, %eax
leaq 0x10(%rsp), %r14
leaq 0xc(%rsp), %r15
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3b91b
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3b926
movq %r14, %rdi
movq %r15, %rdx
callq 0x129f6
movl 0xc(%rsp), %eax
incl %eax
movl %eax, 0xc(%rsp)
cmpl %ebp, %eax
jl 0x3b902
leaq 0xc(%rsp), %r14
movl $0x0, (%r14)
xorl %eax, %eax
leaq 0x30(%rsp), %r15
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3b960
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3b96b
movq %r15, %rdi
movq %r14, %rdx
callq 0x129f6
movl 0xc(%rsp), %ecx
leal 0x1(%rcx), %eax
movl %eax, 0xc(%rsp)
cmpl $0x3, %ecx
jl 0x3b947
movl $0xc, 0xc(%rsp)
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rax
cmpq %rax, %rsi
je 0x3bb0a
movl $0xc, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3bb23
leaq 0x10(%rsp), %rdi
callq 0x129f6
movq 0x10(%r14), %rax
testq %rax, %rax
je 0x3ba55
cmpb $0x0, 0x4(%rax)
jne 0x3ba55
movq 0x10(%rax), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bafb
movl (%rdx), %eax
movl %eax, (%rsi)
jmp 0x3ba4c
leaq 0x51c08(%rip), %rsi     # 0x8d5f8
leaq 0x51bd1(%rip), %rdx     # 0x8d5c8
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3bb58
movq 0x18(%rax), %rdx
addq $0x38, %rdx
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x129f6
jmp 0x3ba55
leaq 0x10(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x2740e
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
movl $0xe, 0xc(%rsp)
cmpq %rax, %rsi
je 0x3baa7
movl $0xe, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
leaq 0x30(%rsp), %rsi
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
callq 0x3c87e
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3ba7e
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3ba95
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq %rbx, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x10(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x2740e
jmp 0x3ba55
leaq 0x10(%rsp), %rdi
callq 0x129f6
movq 0x38(%r15), %r14
testq %r14, %r14
je 0x3ba55
cmpb $0x0, (%r14)
jne 0x3ba55
movq 0x8(%r14), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bc15
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bc1f
leaq 0x10(%rsp), %rdi
callq 0x129f6
jmp 0x3ba55
leaq 0x30(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x2740e
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rax
movl $0xe, 0xc(%rsp)
cmpq %rax, %rsi
je 0x3bb44
movl $0xe, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3ba55
leaq 0x30(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x2740e
jmp 0x3ba55
leaq 0x51a99(%rip), %rsi     # 0x8d5f8
leaq 0x51a7a(%rip), %rdx     # 0x8d5e0
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3bca4
cmpl $0x0, 0x14(%rax)
movq 0x18(%rax), %rbp
movq 0x20(%rax), %r15
je 0x3bc5d
cmpq %r15, %rbp
je 0x3ba55
leaq 0xc(%rsp), %r14
leaq 0x30(%rsp), %r12
movq (%rbp), %r13
cmpl $0xf, 0x38(%r13)
jne 0x3bbdb
movl $0x0, 0xc(%rsp)
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bbce
movl $0x0, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bbdb
leaq 0x10(%rsp), %rdi
movq %r14, %rdx
callq 0x2740e
addq $0x38, %r13
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3bbfc
movl (%r13), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3bc07
movq %r12, %rdi
movq %r13, %rdx
callq 0x129f6
addq $0x8, %rbp
cmpq %r15, %rbp
jne 0x3bb9e
jmp 0x3ba55
leaq 0x10(%rsp), %rdi
callq 0x129f6
movq 0x10(%r14), %rax
testq %rax, %rax
je 0x3ba55
cmpb $0x0, 0x4(%rax)
jne 0x3ba55
movq 0x10(%rax), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
jne 0x3b9e3
leaq 0x10(%rsp), %rdi
callq 0x129f6
jmp 0x3ba55
cmpq %r15, %rbp
je 0x3ba55
leaq 0x10(%rsp), %r14
movq (%rbp), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bc8e
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bc96
movq %r14, %rdi
callq 0x129f6
addq $0x8, %rbp
cmpq %r15, %rbp
jne 0x3bc6b
jmp 0x3ba55
movq 0x5333d(%rip), %rdi     # 0x8efe8
leaq 0x324b6(%rip), %rsi     # 0x6e168
movl $0x8, %edx
callq 0x8330
movq 0x53325(%rip), %rdi     # 0x8efe8
leaq 0x3592f(%rip), %rsi     # 0x715f9
movl $0x22, %edx
callq 0x8330
movq 0x5330d(%rip), %rdi     # 0x8efe8
leaq 0x336de(%rip), %rsi     # 0x6f3c0
movl $0x1, %edx
callq 0x8330
movq 0x532f5(%rip), %rdi     # 0x8efe8
movl $0x4a, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
movl $0xff, %edi
callq 0x8380
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
jmp 0x3bd2f
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3bd49
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3bd60
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq %rbx, %rdi
callq 0x8540