// File: /workspace/github_cpp_makefile_star2_O1/luooofan[P]hblzbd_compiler/src/Pass/arm_liveness_analysis.cpp
// Function: GetDefUsePtr(arm::Instruction*)
std::pair<std::vector<Reg *>, std::vector<Reg *>> GetDefUsePtr(Instruction *inst) {
  std::vector<Reg *> def;
  std::vector<Reg *> use;

  auto process_op2 = [&use](Operand2 *op2) {
    if (nullptr == op2) return;
    if (op2->is_imm_) return;
    use.push_back(op2->reg_);
    if (nullptr != op2->shift_ && !op2->shift_->is_imm_) {
      use.push_back(op2->shift_->shift_reg_);
    }
    return;
  };

  if (auto src_inst = dynamic_cast<BinaryInst *>(inst)) {
    if (nullptr != src_inst->rd_) {
      def.push_back(src_inst->rd_);
    }
    use.push_back(src_inst->rn_);
    process_op2(src_inst->op2_);
  } else if (auto src_inst = dynamic_cast<Move *>(inst)) {
    def.push_back(src_inst->rd_);
    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(new Reg(ArmReg::r0));
      use.push_back(new Reg(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(new Reg(i));
      }
      for (RegId i = 0; i < 4; ++i) {
        def.push_back(new Reg(i));
      }
      def.push_back(new Reg(ArmReg::ip));
      def.push_back(new Reg(ArmReg::lr));
    }
  } else if (auto src_inst = dynamic_cast<LdrStr *>(inst)) {
    if (src_inst->opkind_ == LdrStr::OpKind::LDR) {
      def.push_back(src_inst->rd_);
    } else {
      use.push_back(src_inst->rd_);
    }
    use.push_back(src_inst->rn_);
    process_op2(src_inst->offset_);
  } else if (auto src_inst = dynamic_cast<LdrPseudo *>(inst)) {
    def.push_back(src_inst->rd_);
  } 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);
      }
    } else {
      for (auto reg : src_inst->reg_list_) {
        if (reg->reg_id_ == static_cast<RegId>(ArmReg::pc)) {
          // 此时作为ret语句 视为对r0的使用以及对pc的定义
          use.push_back(new Reg(ArmReg::r0));
        }
        def.push_back(reg);
      }
    }
  } 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, 0x30(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq %r15, 0x10(%rsp)
movaps %xmm0, (%rsp)
testq %rsi, %rsi
je 0x3c230
leaq 0x523ac(%rip), %rsi     # 0x8e5c8
leaq 0x52285(%rip), %rdx     # 0x8e4a8
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r15
testq %r15, %r15
je 0x3c255
movq 0x20(%r15), %rax
testq %rax, %rax
je 0x3c289
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x3c27b
movq %rax, (%rsi)
addq $0x8, 0x28(%rsp)
jmp 0x3c289
testq %r14, %r14
je 0x3c2eb
leaq 0x52363(%rip), %rsi     # 0x8e5c8
leaq 0x5229c(%rip), %rdx     # 0x8e508
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r15
jmp 0x3c2ee
leaq 0x20(%r15), %rdx
leaq 0x20(%rsp), %rdi
callq 0x3d380
leaq 0x28(%r15), %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c2a7
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c2af
movq %rsp, %rdi
callq 0x3d380
movq 0x30(%r15), %r14
testq %r14, %r14
je 0x3c653
cmpb $0x0, (%r14)
jne 0x3c653
leaq 0x8(%r14), %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c380
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c388
xorl %r15d, %r15d
testq %r15, %r15
je 0x3c311
leaq 0x18(%r15), %rdx
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x3c33a
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x28(%rsp)
jmp 0x3c344
testq %r14, %r14
je 0x3c3c0
leaq 0x522a7(%rip), %rsi     # 0x8e5c8
leaq 0x521f8(%rip), %rdx     # 0x8e520
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r15
jmp 0x3c3c3
leaq 0x20(%rsp), %rdi
callq 0x3d380
movq 0x20(%r15), %r14
testq %r14, %r14
je 0x3c653
cmpb $0x0, (%r14)
jne 0x3c653
leaq 0x8(%r14), %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c61c
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c624
movq %rsp, %rdi
callq 0x3d380
movq 0x10(%r14), %rdx
testq %rdx, %rdx
je 0x3c653
cmpb $0x0, 0x4(%rdx)
jne 0x3c653
addq $0x10, %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
jne 0x3c647
movq %rsp, %rdi
callq 0x3d380
jmp 0x3c653
xorl %r15d, %r15d
testq %r15, %r15
je 0x3c46b
movq %r15, %rdi
callq 0xae46
testb %al, %al
je 0x3c494
movl $0x40, %edi
callq 0x8290
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, (%rax)
movq $0x1, 0x8(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movl $0x3f800000, 0x20(%rax) # imm = 0x3F800000
movups %xmm0, 0x28(%rax)
movl $0x0, 0x38(%rax)
leaq 0x18(%rsp), %rsi
movq %rax, (%rsi)
movq %rsp, %rdi
callq 0x3d4a0
movl $0x40, %edi
callq 0x8290
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, (%rax)
movq $0x1, 0x8(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movl $0x3f800000, 0x20(%rax) # imm = 0x3F800000
movups %xmm0, 0x28(%rax)
movl $0xe, 0x38(%rax)
leaq 0x18(%rsp), %rsi
movq %rax, (%rsi)
movq %rsp, %rdi
callq 0x3d4a0
jmp 0x3c653
testq %r14, %r14
je 0x3c6a2
leaq 0x5214d(%rip), %rsi     # 0x8e5c8
leaq 0x520fe(%rip), %rdx     # 0x8e580
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r15
jmp 0x3c6a5
movq %r15, %rdi
callq 0xae10
testb %al, %al
je 0x3c653
addq $0x18, %r15
leaq 0x540e1(%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
testl %eax, %eax
jle 0x3c538
cmpl $0x4, %eax
movl $0x4, %ecx
cmovll %eax, %ecx
cmpl $0x2, %ecx
movl $0x1, %ebp
cmovgel %ecx, %ebp
xorl %r12d, %r12d
movq %rsp, %r14
leaq 0x18(%rsp), %r15
movl $0x40, %edi
callq 0x8290
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, (%rax)
movq $0x1, 0x8(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movl $0x3f800000, 0x20(%rax) # imm = 0x3F800000
movups %xmm0, 0x28(%rax)
movl %r12d, 0x38(%rax)
movq %rax, 0x18(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x3d4a0
incl %r12d
cmpl %r12d, %ebp
jne 0x3c4ee
xorl %ebp, %ebp
leaq 0x20(%rsp), %r14
leaq 0x18(%rsp), %r15
movl $0x40, %edi
callq 0x8290
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, (%rax)
movq $0x1, 0x8(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movl $0x3f800000, 0x20(%rax) # imm = 0x3F800000
movups %xmm0, 0x28(%rax)
movl %ebp, 0x38(%rax)
movq %rax, 0x18(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x3d4a0
incl %ebp
cmpl $0x4, %ebp
jne 0x3c544
movl $0x40, %edi
callq 0x8290
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, (%rax)
movq $0x1, 0x8(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movl $0x3f800000, 0x20(%rax) # imm = 0x3F800000
movups %xmm0, 0x28(%rax)
movl $0xc, 0x38(%rax)
leaq 0x18(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x3d4a0
movl $0x40, %edi
callq 0x8290
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, (%rax)
movq $0x1, 0x8(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movl $0x3f800000, 0x20(%rax) # imm = 0x3F800000
movups %xmm0, 0x28(%rax)
movl $0xe, 0x38(%rax)
leaq 0x18(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x3d4a0
jmp 0x3c653
movq %rsp, %rdi
callq 0x3d380
movq 0x10(%r14), %rdx
testq %rdx, %rdx
je 0x3c653
cmpb $0x0, 0x4(%rdx)
jne 0x3c653
addq $0x10, %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c704
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
leaq 0x20(%rsp), %rsi
movq %rsp, %rdx
movq %rbx, %rdi
callq 0x3ce54
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x3c679
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x3c690
movq 0x30(%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
xorl %r15d, %r15d
testq %r15, %r15
je 0x3c6cf
leaq 0x20(%r15), %rdx
cmpl $0x0, 0x14(%r15)
je 0x3c6f5
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c711
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c719
testq %r14, %r14
je 0x3c774
leaq 0x51ee9(%rip), %rsi     # 0x8e5c8
leaq 0x51eb2(%rip), %rdx     # 0x8e598
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
jmp 0x3c776
leaq 0x20(%rsp), %rdi
movq %rdx, %rsi
callq 0x3ce36
jmp 0x3c719
movq %rsp, %rdi
callq 0x3d380
jmp 0x3c653
movq %rsp, %rdi
callq 0x3d380
leaq 0x28(%r15), %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c737
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c73f
movq %rsp, %rdi
callq 0x3d380
movq 0x38(%r15), %r14
testq %r14, %r14
je 0x3c653
cmpb $0x0, (%r14)
jne 0x3c653
leaq 0x8(%r14), %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c7b0
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c7b8
xorl %eax, %eax
testq %rax, %rax
je 0x3c791
addq $0x18, %rax
leaq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0x3ce36
jmp 0x3c653
testq %r14, %r14
je 0x3c7f0
leaq 0x51e2b(%rip), %rsi     # 0x8e5c8
leaq 0x51e0c(%rip), %rdx     # 0x8e5b0
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
jmp 0x3c7f2
movq %rsp, %rdi
callq 0x3d380
movq 0x10(%r14), %rdx
testq %rdx, %rdx
je 0x3c653
cmpb $0x0, 0x4(%rdx)
jne 0x3c653
addq $0x10, %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
jne 0x3c647
movq %rsp, %rdi
callq 0x3d380
jmp 0x3c653
xorl %eax, %eax
testq %rax, %rax
je 0x3c8fc
cmpl $0x0, 0x14(%rax)
movq 0x18(%rax), %rbp
movq 0x20(%rax), %r12
je 0x3c8b2
cmpq %r12, %rbp
je 0x3c653
movq %rsp, %r14
leaq 0x40(%rsp), %r15
leaq 0x18(%rsp), %r13
movq (%rbp), %rax
movq %rax, 0x18(%rsp)
cmpl $0xf, 0x38(%rax)
jne 0x3c877
movl $0x40, %edi
callq 0x8290
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, (%rax)
movq $0x1, 0x8(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movl $0x3f800000, 0x20(%rax) # imm = 0x3F800000
movups %xmm0, 0x28(%rax)
movl $0x0, 0x38(%rax)
movq %rax, 0x40(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x3d4a0
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x3c893
movq 0x18(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x28(%rsp)
jmp 0x3c8a0
leaq 0x20(%rsp), %rdi
movq %r13, %rdx
callq 0x3d380
addq $0x8, %rbp
cmpq %r12, %rbp
jne 0x3c823
jmp 0x3c653
cmpq %r12, %rbp
je 0x3c653
movq %rsp, %r14
leaq 0x18(%rsp), %r15
movq (%rbp), %rax
movq %rax, 0x18(%rsp)
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c8e3
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c8ee
movq %r14, %rdi
movq %r15, %rdx
callq 0x3d380
addq $0x8, %rbp
cmpq %r12, %rbp
jne 0x3c8c3
jmp 0x3c653
movq 0x536ed(%rip), %rdi     # 0x8fff0
leaq 0x3285e(%rip), %rsi     # 0x6f168
movl $0x8, %edx
callq 0x8330
movq 0x536d5(%rip), %rdi     # 0x8fff0
leaq 0x35cd1(%rip), %rsi     # 0x725f3
movl $0x22, %edx
callq 0x8330
movq 0x536bd(%rip), %rdi     # 0x8fff0
leaq 0x33a86(%rip), %rsi     # 0x703c0
movl $0x1, %edx
callq 0x8330
movq 0x536a5(%rip), %rdi     # 0x8fff0
movl $0x94, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
movl $0xff, %edi
callq 0x8380
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
jmp 0x3c987
movq %rax, %rbx
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x3c9a0
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x3c9b7
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq %rbx, %rdi
callq 0x8540
nop