// File: luooofan[P]hblzbd_compiler/src/Pass/ir_liveness_analysis.cpp
// Function: GetDefUsePtr(ir::IR*, bool)
std::pair<std::vector<Opn *>, std::vector<Opn *>> GetDefUsePtr(IR *ir, bool consider) {
  std::vector<Opn *> def;
  std::vector<Opn *> use;

  auto process_opn = [&use, &consider](Opn *op) {
    if (nullptr == op) return;
    if (op->type_ == Opn::Type::Imm || op->type_ == Opn::Type::Label || op->type_ == Opn::Type::Func ||
        op->type_ == Opn::Type::Null)
      return;
    if (op->type_ == Opn::Type::Array) {
      if (consider) use.push_back(op);
      if (op->offset_->type_ == Opn::Type::Var)
        if (consider || 0 != op->offset_->scope_id_) use.push_back(op->offset_);
    } else {  // var
      if (!consider && 0 == op->scope_id_) return;
      use.push_back(op);
    }
  };

  auto process_res = [&def, &use, &consider](Opn *res) {
    if (nullptr == res) return;
    if (res->type_ == Opn::Type::Label || res->type_ == Opn::Type::Func || res->type_ == Opn::Type::Null) return;
    if (res->type_ == Opn::Type::Array) {
      if (consider) def.push_back(res);
      if (res->offset_->type_ == Opn::Type::Var)
        if (consider || 0 != res->offset_->scope_id_) use.push_back(res->offset_);
    } else {  // var
      if (!consider && 0 == res->scope_id_) return;
      def.push_back(res);
    }
  };

  if (ir->op_ == IR::OpKind::ADD || ir->op_ == IR::OpKind::SUB || ir->op_ == IR::OpKind::MUL ||
      ir->op_ == IR::OpKind::DIV || ir->op_ == IR::OpKind::MOD) {
    process_opn(&(ir->opn1_));
    process_opn(&(ir->opn2_));
    process_res(&(ir->res_));
  } else if (ir->op_ == IR::OpKind::NOT || ir->op_ == IR::OpKind::NEG) {
    process_opn(&(ir->opn1_));
    process_res(&(ir->res_));
  } else if (ir->op_ == IR::OpKind::LABEL) {
    return {def, use};
  } else if (ir->op_ == IR::OpKind::PARAM) {
    process_opn(&(ir->opn1_));
  } else if (ir->op_ == IR::OpKind::CALL) {
    process_res(&(ir->res_));
  } else if (ir->op_ == IR::OpKind::RET) {
    process_opn(&(ir->opn1_));
  } else if (ir->op_ == IR::OpKind::GOTO) {
    return {def, use};
  } else if (ir->op_ == IR::OpKind::ASSIGN) {
    process_opn(&(ir->opn1_));
    process_res(&(ir->res_));
  } else if (ir->op_ == IR::OpKind::JEQ || ir->op_ == IR::OpKind::JNE || ir->op_ == IR::OpKind::JLT ||
             ir->op_ == IR::OpKind::JLE || ir->op_ == IR::OpKind::JGT || ir->op_ == IR::OpKind::JGE) {
    process_opn(&(ir->opn1_));
    process_opn(&(ir->opn2_));
  } else if (ir->op_ == IR::OpKind::VOID) {
    return {def, use};
  } else if (ir->op_ == IR::OpKind::ASSIGN_OFFSET) {
    process_opn(&(ir->opn1_));
    process_res(&(ir->res_));
  } else if (ir->op_ == IR::OpKind::PHI) {
    for (auto &arg : ir->phi_args_) {
      process_opn(&(arg));
    }
    process_res(&(ir->res_));
  } else if (ir->op_ == IR::OpKind::ALLOCA) {
    process_res(&(ir->opn1_));
  } else if (ir->op_ == IR::OpKind::DECLARE) {
    process_res(&(ir->opn1_));
  } else {
    MyAssert(0);
  }

  return {def, use};
}

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0x28(%rsp)
movb %dl, %al
movq %rdi, %rcx
movq %rcx, 0x30(%rsp)
movq %rdi, 0xd0(%rsp)
movq %rsi, 0xc8(%rsp)
andb $0x1, %al
movb %al, 0xc7(%rsp)
leaq 0xa8(%rsp), %rdi
callq 0xc9eb0
leaq 0x90(%rsp), %rdi
callq 0xc9eb0
leaq 0x90(%rsp), %rax
movq %rax, 0x80(%rsp)
leaq 0xc7(%rsp), %rax
movq %rax, 0x88(%rsp)
leaq 0xa8(%rsp), %rax
movq %rax, 0x68(%rsp)
leaq 0x90(%rsp), %rax
movq %rax, 0x70(%rsp)
leaq 0xc7(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0xc8(%rsp), %rax
cmpl $0x0, (%rax)
je 0xc7cf5
movq 0xc8(%rsp), %rax
cmpl $0x1, (%rax)
je 0xc7cf5
movq 0xc8(%rsp), %rax
cmpl $0x2, (%rax)
je 0xc7cf5
movq 0xc8(%rsp), %rax
cmpl $0x3, (%rax)
je 0xc7cf5
movq 0xc8(%rsp), %rax
cmpl $0x4, (%rax)
jne 0xc7d78
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7d10
movq 0xc8(%rsp), %rsi
addq $0x48, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7d2b
movq 0xc8(%rsp), %rsi
addq $0x88, %rsi
leaq 0x68(%rsp), %rdi
callq 0xc82f0
jmp 0xc7d46
jmp 0xc819f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x92a70
leaq 0xa8(%rsp), %rdi
callq 0x92a70
jmp 0xc81ea
movq 0xc8(%rsp), %rax
cmpl $0x5, (%rax)
je 0xc7d92
movq 0xc8(%rsp), %rax
cmpl $0x6, (%rax)
jne 0xc7dcd
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7dad
movq 0xc8(%rsp), %rsi
addq $0x88, %rsi
leaq 0x68(%rsp), %rdi
callq 0xc82f0
jmp 0xc7dc8
jmp 0xc819d
movq 0xc8(%rsp), %rax
cmpl $0x7, (%rax)
jne 0xc7e03
movq 0x28(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
leaq 0x90(%rsp), %rdx
callq 0xc9ec0
jmp 0xc7df6
movl $0x1, 0x58(%rsp)
jmp 0xc81c3
movq 0xc8(%rsp), %rax
cmpl $0x8, (%rax)
jne 0xc7e30
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7e2b
jmp 0xc8199
movq 0xc8(%rsp), %rax
cmpl $0x9, (%rax)
jne 0xc7e5d
movq 0xc8(%rsp), %rsi
addq $0x88, %rsi
leaq 0x68(%rsp), %rdi
callq 0xc82f0
jmp 0xc7e58
jmp 0xc8197
movq 0xc8(%rsp), %rax
cmpl $0xa, (%rax)
jne 0xc7e8a
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7e85
jmp 0xc8195
movq 0xc8(%rsp), %rax
cmpl $0xb, (%rax)
jne 0xc7ec0
movq 0x28(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
leaq 0x90(%rsp), %rdx
callq 0xc9ec0
jmp 0xc7eb3
movl $0x1, 0x58(%rsp)
jmp 0xc81c3
movq 0xc8(%rsp), %rax
cmpl $0xc, (%rax)
jne 0xc7f08
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7ee8
movq 0xc8(%rsp), %rsi
addq $0x88, %rsi
leaq 0x68(%rsp), %rdi
callq 0xc82f0
jmp 0xc7f03
jmp 0xc8191
movq 0xc8(%rsp), %rax
cmpl $0xd, (%rax)
je 0xc7f56
movq 0xc8(%rsp), %rax
cmpl $0xe, (%rax)
je 0xc7f56
movq 0xc8(%rsp), %rax
cmpl $0xf, (%rax)
je 0xc7f56
movq 0xc8(%rsp), %rax
cmpl $0x10, (%rax)
je 0xc7f56
movq 0xc8(%rsp), %rax
cmpl $0x11, (%rax)
je 0xc7f56
movq 0xc8(%rsp), %rax
cmpl $0x12, (%rax)
jne 0xc7f91
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7f71
movq 0xc8(%rsp), %rsi
addq $0x48, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7f8c
jmp 0xc818f
movq 0xc8(%rsp), %rax
cmpl $0x13, (%rax)
jne 0xc7fc7
movq 0x28(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
leaq 0x90(%rsp), %rdx
callq 0xc9ec0
jmp 0xc7fba
movl $0x1, 0x58(%rsp)
jmp 0xc81c3
movq 0xc8(%rsp), %rax
cmpl $0x14, (%rax)
jne 0xc800f
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc7fef
movq 0xc8(%rsp), %rsi
addq $0x88, %rsi
leaq 0x68(%rsp), %rdi
callq 0xc82f0
jmp 0xc800a
jmp 0xc818b
movq 0xc8(%rsp), %rax
cmpl $0x15, (%rax)
jne 0xc80b7
movq 0xc8(%rsp), %rax
addq $0xc8, %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rdi
callq 0x47fb0
movq %rax, 0x48(%rsp)
movq 0x50(%rsp), %rdi
callq 0x47fe0
movq %rax, 0x40(%rsp)
leaq 0x48(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x48010
testb $0x1, %al
jne 0xc8066
jmp 0xc8097
leaq 0x48(%rsp), %rdi
callq 0x48050
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rsi
leaq 0x80(%rsp), %rdi
callq 0xc8200
jmp 0xc8089
jmp 0xc808b
leaq 0x48(%rsp), %rdi
callq 0x48060
jmp 0xc8051
movq 0xc8(%rsp), %rsi
addq $0x88, %rsi
leaq 0x68(%rsp), %rdi
callq 0xc82f0
jmp 0xc80b2
jmp 0xc8189
movq 0xc8(%rsp), %rax
cmpl $0x16, (%rax)
jne 0xc80e1
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x68(%rsp), %rdi
callq 0xc82f0
jmp 0xc80dc
jmp 0xc8187
movq 0xc8(%rsp), %rax
cmpl $0x17, (%rax)
jne 0xc8108
movq 0xc8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x68(%rsp), %rdi
callq 0xc82f0
jmp 0xc8106
jmp 0xc8185
movq 0x83ed9(%rip), %rdi     # 0x14bfe8
leaq 0x31fe2(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, 0x20(%rsp)
jmp 0xc8122
movq 0x20(%rsp), %rdi
leaq 0x3597d(%rip), %rsi     # 0xfdaab
callq 0x8330
movq %rax, 0x18(%rsp)
jmp 0xc813a
movq 0x18(%rsp), %rdi
leaq 0x332a4(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, 0x10(%rsp)
jmp 0xc8152
movq 0x10(%rsp), %rdi
movl $0x4d, %esi
callq 0x8650
movq %rax, 0x8(%rsp)
jmp 0xc8168
movq 0x8(%rsp), %rdi
movq 0x83e0c(%rip), %rsi     # 0x14bf80
callq 0x8380
jmp 0xc817b
movl $0xff, %edi
callq 0x8460
jmp 0xc8187
jmp 0xc8189
jmp 0xc818b
jmp 0xc818d
jmp 0xc818f
jmp 0xc8191
jmp 0xc8193
jmp 0xc8195
jmp 0xc8197
jmp 0xc8199
jmp 0xc819b
jmp 0xc819d
jmp 0xc819f
movq 0x28(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
leaq 0x90(%rsp), %rdx
callq 0xc9ec0
jmp 0xc81bb
movl $0x1, 0x58(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x92a70
leaq 0xa8(%rsp), %rdi
callq 0x92a70
movq 0x30(%rsp), %rax
addq $0xd8, %rsp
retq
movq 0x60(%rsp), %rdi
callq 0x8670
nopw %cs:(%rax,%rax)