// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
leaq 0xf(%rsp), %rax
movb %dl, (%rax)
xorps %xmm0, %xmm0
leaq 0x40(%rsp), %rcx
movaps %xmm0, (%rcx)
andq $0x0, 0x10(%rcx)
leaq 0x20(%rsp), %rdx
andq $0x0, 0x10(%rdx)
movaps %xmm0, (%rdx)
movq %rdx, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq %rcx, 0x60(%rsp)
movq %rdx, 0x68(%rsp)
movq %rax, 0x70(%rsp)
movl (%rsi), %eax
cmpq $0x17, %rax
ja 0x4645a
movq %rsi, %r14
movq %rdi, %rbx
movl $0x88, %r13d
pushq $0x8
popq %rsi
leaq 0x1353b(%rip), %rcx     # 0x598d4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x8(%r14), %rsi
leaq 0x10(%rsp), %rdi
callq 0x464ca
pushq $0x48
popq %rsi
addq %rsi, %r14
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x464ca
jmp 0x463f3
leaq 0x8(%r14), %rsi
leaq 0x10(%rsp), %rdi
callq 0x464ca
pushq $0x48
popq %rsi
addq %r14, %rsi
leaq 0x10(%rsp), %rdi
callq 0x464ca
addq %r13, %r14
leaq 0x60(%rsp), %rdi
movq %r14, %rsi
callq 0x4654c
leaq 0x40(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %rbx, %rdi
callq 0x46f2c
leaq 0x20(%rsp), %rdi
callq 0x366f8
leaq 0x40(%rsp), %rdi
callq 0x366f8
movq %rbx, %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x8
popq %r13
jmp 0x463e3
movq 0xc8(%r14), %r15
movq 0xd0(%r14), %rbp
leaq 0x10(%rsp), %r12
cmpq %rbp, %r15
je 0x463e3
movq %r12, %rdi
movq %r15, %rsi
callq 0x464ca
addq $0x40, %r15
jmp 0x46444
movq 0x3ab87(%rip), %rdi     # 0x80fe8
leaq 0xfc80(%rip), %rsi      # 0x560e8
callq 0x8240
leaq 0x13535(%rip), %rsi     # 0x599a9
movq %rax, %rdi
callq 0x8240
leaq 0x10e9d(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
pushq $0x4d
popq %rsi
movq %rax, %rdi
callq 0x84b0
movq %rax, %rdi
callq 0x8170
movl $0xff, %edi
callq 0x8300
jmp 0x464aa
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x366f8
leaq 0x40(%rsp), %rdi
callq 0x366f8
movq %rbx, %rdi
callq 0x84d0
nop