// File: /workspace/github_cpp_makefile_star2_O1/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
movq %rsi, %r14
movq %rdi, %rbx
xorl %r15d, %r15d
movq %r15, 0x40(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movq %r15, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
testq %rsi, %rsi
je 0x3ba52
leaq 0x52b8a(%rip), %rsi     # 0x8e5c8
leaq 0x52a63(%rip), %rdx     # 0x8e4a8
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r15
testq %r15, %r15
je 0x3ba7f
movq 0x20(%r15), %rdx
testq %rdx, %rdx
je 0x3baaf
addq $0x38, %rdx
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3baa5
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3baaf
testq %r14, %r14
je 0x3bb1d
leaq 0x52b39(%rip), %rsi     # 0x8e5c8
leaq 0x52a72(%rip), %rdx     # 0x8e508
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r15
jmp 0x3bb20
leaq 0x30(%rsp), %rdi
callq 0x12d38
movq 0x28(%r15), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bad2
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3badc
leaq 0x10(%rsp), %rdi
callq 0x12d38
movq 0x30(%r15), %r14
testq %r14, %r14
je 0x3c0cd
cmpb $0x0, (%r14)
jne 0x3c0cd
movq 0x8(%r14), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bbbc
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bbc6
xorl %r15d, %r15d
testq %r15, %r15
je 0x3bb48
movq 0x18(%r15), %rdx
addq $0x38, %rdx
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3bb71
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3bb7b
testq %r14, %r14
je 0x3bc04
leaq 0x52a70(%rip), %rsi     # 0x8e5c8
leaq 0x529c1(%rip), %rdx     # 0x8e520
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r15
jmp 0x3bc07
leaq 0x30(%rsp), %rdi
callq 0x12d38
movq 0x20(%r15), %r14
testq %r14, %r14
je 0x3c0cd
cmpb $0x0, (%r14)
jne 0x3c0cd
movq 0x8(%r14), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bd6a
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bd74
leaq 0x10(%rsp), %rdi
callq 0x12d38
movq 0x10(%r14), %rax
testq %rax, %rax
je 0x3c0cd
cmpb $0x0, 0x4(%rax)
jne 0x3c0cd
movq 0x10(%rax), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
jne 0x3bda3
leaq 0x10(%rsp), %rdi
callq 0x12d38
jmp 0x3c0cd
xorl %r15d, %r15d
testq %r15, %r15
je 0x3bc44
movq %r15, %rdi
callq 0xae46
testb %al, %al
je 0x3bc6d
movl $0x0, 0xc(%rsp)
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3be07
movl $0x0, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3be16
testq %r14, %r14
je 0x3bdac
leaq 0x52974(%rip), %rsi     # 0x8e5c8
leaq 0x52925(%rip), %rdx     # 0x8e580
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r15
jmp 0x3bdaf
movq %r15, %rdi
callq 0xae10
testb %al, %al
je 0x3c0cd
addq $0x18, %r15
leaq 0x54908(%rip), %rdi     # 0x90590
movq %r15, %rsi
callq 0x3d232
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 0x3bcf7
xorl %eax, %eax
leaq 0x10(%rsp), %r14
leaq 0xc(%rsp), %r15
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bcde
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bce9
movq %r14, %rdi
movq %r15, %rdx
callq 0x12d38
movl 0xc(%rsp), %eax
incl %eax
movl %eax, 0xc(%rsp)
cmpl %ebp, %eax
jl 0x3bcc5
leaq 0xc(%rsp), %r14
movl $0x0, (%r14)
xorl %eax, %eax
leaq 0x30(%rsp), %r15
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3bd23
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3bd2e
movq %r15, %rdi
movq %r14, %rdx
callq 0x12d38
movl 0xc(%rsp), %ecx
leal 0x1(%rcx), %eax
movl %eax, 0xc(%rsp)
cmpl $0x3, %ecx
jl 0x3bd0a
movl $0xc, 0xc(%rsp)
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3be86
movl $0xc, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3be95
leaq 0x10(%rsp), %rdi
callq 0x12d38
movq 0x10(%r14), %rax
testq %rax, %rax
je 0x3c0cd
cmpb $0x0, 0x4(%rax)
jne 0x3c0cd
movq 0x10(%rax), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3be77
movl (%rdx), %eax
movl %eax, (%rsi)
jmp 0x3be30
xorl %r15d, %r15d
testq %r15, %r15
je 0x3bde1
movq 0x20(%r15), %rdx
addq $0x38, %rdx
cmpl $0x0, 0x14(%r15)
je 0x3be52
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bec5
leaq 0x18(%rsp), %rax
jmp 0x3be67
testq %r14, %r14
je 0x3becc
leaq 0x527d7(%rip), %rsi     # 0x8e5c8
leaq 0x527a0(%rip), %rdx     # 0x8e598
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
jmp 0x3bece
leaq 0x10(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x26d72
movl $0xe, 0xc(%rsp)
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3be3e
movl $0xe, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3c0cd
leaq 0x10(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x26d72
jmp 0x3c0cd
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3bf23
leaq 0x38(%rsp), %rax
movl (%rdx), %ecx
movl %ecx, (%rsi)
addq $0x4, %rsi
movq %rsi, (%rax)
jmp 0x3bf2d
leaq 0x10(%rsp), %rdi
callq 0x12d38
jmp 0x3c0cd
leaq 0x30(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x26d72
movl $0xe, 0xc(%rsp)
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3beb1
movl $0xe, (%rsi)
jmp 0x3beef
leaq 0x30(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x26d72
jmp 0x3c0cd
leaq 0x10(%rsp), %rdi
jmp 0x3bf28
xorl %eax, %eax
testq %rax, %rax
je 0x3befd
movq 0x18(%rax), %rdx
addq $0x38, %rdx
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3bf94
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3c0cd
testq %r14, %r14
je 0x3bfeb
leaq 0x526bb(%rip), %rsi     # 0x8e5c8
leaq 0x5269c(%rip), %rdx     # 0x8e5b0
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
jmp 0x3bfed
leaq 0x30(%rsp), %rdi
callq 0x12d38
movq 0x28(%r15), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bf50
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bf5a
leaq 0x10(%rsp), %rdi
callq 0x12d38
movq 0x38(%r15), %r14
testq %r14, %r14
je 0x3c0cd
cmpb $0x0, (%r14)
jne 0x3c0cd
movq 0x8(%r14), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3bfa3
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3bfad
leaq 0x30(%rsp), %rdi
callq 0x12d38
jmp 0x3c0cd
leaq 0x10(%rsp), %rdi
callq 0x12d38
movq 0x10(%r14), %rax
testq %rax, %rax
je 0x3c0cd
cmpb $0x0, 0x4(%rax)
jne 0x3c0cd
movq 0x10(%rax), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
jne 0x3bda3
leaq 0x10(%rsp), %rdi
callq 0x12d38
jmp 0x3c0cd
xorl %eax, %eax
testq %rax, %rax
je 0x3c11f
cmpl $0x0, 0x14(%rax)
movq 0x18(%rax), %rbp
movq 0x20(%rax), %r15
je 0x3c08f
cmpq %r15, %rbp
je 0x3c0cd
leaq 0xc(%rsp), %r14
leaq 0x30(%rsp), %r12
movq (%rbp), %r13
cmpl $0xf, 0x38(%r13)
jne 0x3c058
movl $0x0, 0xc(%rsp)
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3c04b
movl $0x0, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3c058
leaq 0x10(%rsp), %rdi
movq %r14, %rdx
callq 0x26d72
addq $0x38, %r13
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x3c079
movl (%r13), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x3c084
movq %r12, %rdi
movq %r13, %rdx
callq 0x12d38
addq $0x8, %rbp
cmpq %r15, %rbp
jne 0x3c01b
jmp 0x3c0cd
cmpq %r15, %rbp
je 0x3c0cd
leaq 0x10(%rsp), %r14
movq (%rbp), %rdx
addq $0x38, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x3c0bc
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x3c0c4
movq %r14, %rdi
callq 0x12d38
addq $0x8, %rbp
cmpq %r15, %rbp
jne 0x3c099
leaq 0x30(%rsp), %rsi
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
callq 0x3cdf4
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3c0f6
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3c10d
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
movq 0x53eca(%rip), %rdi     # 0x8fff0
leaq 0x3303b(%rip), %rsi     # 0x6f168
movl $0x8, %edx
callq 0x8330
movq 0x53eb2(%rip), %rdi     # 0x8fff0
leaq 0x364ae(%rip), %rsi     # 0x725f3
movl $0x22, %edx
callq 0x8330
movq 0x53e9a(%rip), %rdi     # 0x8fff0
leaq 0x34263(%rip), %rsi     # 0x703c0
movl $0x1, %edx
callq 0x8330
movq 0x53e82(%rip), %rdi     # 0x8fff0
movl $0x4a, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
movl $0xff, %edi
callq 0x8380
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
jmp 0x3c1aa
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3c1c4
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3c1db
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq %rbx, %rdi
callq 0x8540