// File: /workspace/github_cpp_makefile_star2_O3/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
xorl %eax, %eax
movq %rax, 0x30(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq %rax, 0x10(%rsp)
movaps %xmm0, (%rsp)
testq %rsi, %rsi
je 0x3c420
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x51854(%rip), %rsi     # 0x8d5f8
leaq 0x5172d(%rip), %rdx     # 0x8d4d8
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3be00
movq %rax, %r15
cmpq $0x0, 0x20(%rax)
je 0x3be70
leaq 0x20(%r15), %rdx
leaq 0x20(%rsp), %rdi
xorl %esi, %esi
callq 0x3ce18
movq 0x8(%rsp), %rsi
movq %r15, %rdx
addq $0x28, %rdx
cmpq 0x10(%rsp), %rsi
je 0x3be79
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3be81
leaq 0x517f1(%rip), %rsi     # 0x8d5f8
leaq 0x5172a(%rip), %rdx     # 0x8d538
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3bebd
movq %rax, %r15
leaq 0x18(%rax), %rdx
leaq 0x20(%rsp), %rdi
xorl %esi, %esi
callq 0x3ce18
movq 0x20(%r15), %r14
testq %r14, %r14
je 0x3c1b9
cmpb $0x0, (%r14)
jne 0x3c1b9
leaq 0x8(%r14), %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c182
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c18a
movq %r15, %rdx
addq $0x28, %rdx
xorl %esi, %esi
movq %rsp, %rdi
callq 0x3ce18
movq 0x30(%r15), %r14
testq %r14, %r14
je 0x3c1b9
cmpb $0x0, (%r14)
jne 0x3c1b9
leaq 0x8(%r14), %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3bf80
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3bf88
leaq 0x51734(%rip), %rsi     # 0x8d5f8
leaq 0x51685(%rip), %rdx     # 0x8d550
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3bfc0
movq %rax, %r15
movq %rax, %rdi
callq 0xab90
testb %al, %al
je 0x3c005
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 0x3cf38
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 0x3cf38
jmp 0x3c1b9
movq %rsp, %rdi
callq 0x3ce18
movq 0x10(%r14), %rdx
testq %rdx, %rdx
je 0x3c1b9
cmpb $0x0, 0x4(%rdx)
jne 0x3c1b9
addq $0x10, %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
jne 0x3c1ad
movq %rsp, %rdi
callq 0x3ce18
jmp 0x3c1b9
leaq 0x51631(%rip), %rsi     # 0x8d5f8
leaq 0x515e2(%rip), %rdx     # 0x8d5b0
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3c208
movq %rax, %r15
movq %rax, %r14
leaq 0x20(%rax), %rdx
cmpl $0x0, 0x14(%r15)
je 0x3c23f
movq %rsp, %rdi
xorl %esi, %esi
callq 0x3ce18
jmp 0x3c24c
movq %r15, %rdi
callq 0xab5a
testb %al, %al
je 0x3c1b9
addq $0x18, %r15
leaq 0x53570(%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
testl %eax, %eax
jle 0x3c09e
cmpl $0x4, %eax
movl $0x4, %ebp
cmovbl %eax, %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 0x3cf38
incl %r12d
cmpl %r12d, %ebp
jne 0x3c054
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 0x3cf38
incl %ebp
cmpl $0x4, %ebp
jne 0x3c0aa
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 0x3cf38
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 0x3cf38
jmp 0x3c1b9
movq %rsp, %rdi
callq 0x3ce18
movq 0x10(%r14), %rdx
testq %rdx, %rdx
je 0x3c1b9
cmpb $0x0, 0x4(%rdx)
jne 0x3c1b9
addq $0x10, %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c2b1
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
leaq 0x20(%rsp), %rsi
movq %rsp, %rdx
movq %rbx, %rdi
callq 0x3c8de
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x3c1df
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x3c1f6
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
leaq 0x513e9(%rip), %rsi     # 0x8d5f8
leaq 0x513b2(%rip), %rdx     # 0x8d5c8
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3c2be
addq $0x18, %rax
leaq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0x3c8c0
jmp 0x3c1b9
leaq 0x20(%rsp), %rdi
movq %rdx, %rsi
callq 0x3c8c0
addq $0x28, %r15
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c26a
movq (%r15), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c275
movq %rsp, %rdi
movq %r15, %rdx
callq 0x3ce18
movq 0x38(%r14), %r14
testq %r14, %r14
je 0x3c1b9
cmpb $0x0, (%r14)
jne 0x3c1b9
leaq 0x8(%r14), %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c396
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c39e
movq %rsp, %rdi
callq 0x3ce18
jmp 0x3c1b9
leaq 0x51333(%rip), %rsi     # 0x8d5f8
leaq 0x51314(%rip), %rdx     # 0x8d5e0
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x3c420
cmpl $0x0, 0x14(%rax)
movq 0x18(%rax), %rbp
movq 0x20(%rax), %r12
je 0x3c3d6
cmpq %r12, %rbp
je 0x3c1b9
movq %rsp, %r14
leaq 0x40(%rsp), %r15
leaq 0x18(%rsp), %r13
movq (%rbp), %rax
movq %rax, 0x18(%rsp)
cmpl $0xf, 0x38(%rax)
jne 0x3c35b
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 0x3cf38
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x3c377
movq 0x18(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x28(%rsp)
jmp 0x3c384
leaq 0x20(%rsp), %rdi
movq %r13, %rdx
callq 0x3ce18
addq $0x8, %rbp
cmpq %r12, %rbp
jne 0x3c307
jmp 0x3c1b9
movq %rsp, %rdi
callq 0x3ce18
movq 0x10(%r14), %rdx
testq %rdx, %rdx
je 0x3c1b9
cmpb $0x0, 0x4(%rdx)
jne 0x3c1b9
addq $0x10, %rdx
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
jne 0x3c1ad
movq %rsp, %rdi
callq 0x3ce18
jmp 0x3c1b9
cmpq %r12, %rbp
je 0x3c1b9
movq %rsp, %r14
leaq 0x18(%rsp), %r15
movq (%rbp), %rax
movq %rax, 0x18(%rsp)
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x3c407
movq %rax, (%rsi)
addq $0x8, 0x8(%rsp)
jmp 0x3c412
movq %r14, %rdi
movq %r15, %rdx
callq 0x3ce18
addq $0x8, %rbp
cmpq %r12, %rbp
jne 0x3c3e7
jmp 0x3c1b9
movq 0x52bc1(%rip), %rdi     # 0x8efe8
leaq 0x31d3a(%rip), %rsi     # 0x6e168
movl $0x8, %edx
callq 0x8330
movq 0x52ba9(%rip), %rdi     # 0x8efe8
leaq 0x351b3(%rip), %rsi     # 0x715f9
movl $0x22, %edx
callq 0x8330
movq 0x52b91(%rip), %rdi     # 0x8efe8
leaq 0x32f62(%rip), %rsi     # 0x6f3c0
movl $0x1, %edx
callq 0x8330
movq 0x52b79(%rip), %rdi     # 0x8efe8
movl $0x94, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
movl $0xff, %edi
callq 0x8380
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
jmp 0x3c4ab
movq %rax, %rbx
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x3c4c4
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x3c4db
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x82a0
movq %rbx, %rdi
callq 0x8540
nop