// File: /workspace/github_cpp_makefile_star2_O3/luooofan[P]hblzbd_compiler/src/Pass/ir_liveness_analysis.cpp
// Function: GetDefUse[abi:cxx11](ir::IR*, bool)
std::pair<std::vector<std::string>, std::vector<std::string>> GetDefUse(IR *ir, bool consider) {
  std::vector<std::string> def;
  std::vector<std::string> 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->name_ + "." + std::to_string(op->scope_id_));
      if (op->offset_->type_ == Opn::Type::Var)
        if (consider || 0 != op->offset_->scope_id_)
          use.push_back(op->offset_->name_ + "." + std::to_string(op->offset_->scope_id_));
    } else {  // var
      if (!consider && 0 == op->scope_id_) return;
      use.push_back(op->name_ + "." + std::to_string(op->scope_id_));
    }
  };

  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->name_ + "." + std::to_string(res->scope_id_));
      if (res->offset_->type_ == Opn::Type::Var)
        if (consider || 0 != res->offset_->scope_id_)
          use.push_back(res->offset_->name_ + "." + std::to_string(res->offset_->scope_id_));
    } else {
      if (!consider && 0 == res->scope_id_) return;
      def.push_back(res->name_ + "." + std::to_string(res->scope_id_));
    }
  };

  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
movq %rsi, %r14
leaq 0xf(%rsp), %rax
movb %dl, (%rax)
xorl %ecx, %ecx
leaq 0x40(%rsp), %rdx
movq %rcx, 0x10(%rdx)
xorps %xmm0, %xmm0
movaps %xmm0, (%rdx)
leaq 0x20(%rsp), %rsi
movq %rcx, 0x10(%rsi)
movaps %xmm0, (%rsi)
movq %rsi, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq %rdx, 0x60(%rsp)
movq %rsi, 0x68(%rsp)
movq %rax, 0x70(%rsp)
movl (%r14), %eax
cmpq $0x17, %rax
ja 0x589d7
movq %rdi, %rbx
movl $0x88, %r13d
movl $0x8, %r15d
leaq 0x190ce(%rip), %rcx     # 0x719d4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x8(%r14), %rsi
movl $0x48, %r15d
leaq 0x10(%rsp), %rdi
callq 0x58a64
addq %r15, %r14
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x58a64
jmp 0x58969
leaq 0x8(%r14), %rsi
movl $0x48, %r15d
leaq 0x10(%rsp), %rdi
callq 0x58a64
addq %r14, %r15
leaq 0x10(%rsp), %rdi
movq %r15, %rsi
callq 0x58a64
addq %r13, %r14
leaq 0x60(%rsp), %rdi
movq %r14, %rsi
callq 0x590be
leaq 0x40(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %rbx, %rdi
callq 0x59cba
leaq 0x20(%rsp), %rdi
callq 0x45cd2
leaq 0x40(%rsp), %rdi
callq 0x45cd2
movq %rbx, %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x8, %r13d
jmp 0x58959
movq 0xc8(%r14), %r15
movq 0xd0(%r14), %rbp
cmpq %rbp, %r15
je 0x58959
leaq 0x10(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x58a64
addq $0x40, %r15
cmpq %rbp, %r15
jne 0x589c1
jmp 0x58959
movq 0x3660a(%rip), %rdi     # 0x8efe8
leaq 0x15783(%rip), %rsi     # 0x6e168
movl $0x8, %edx
callq 0x8330
movq 0x365f2(%rip), %rdi     # 0x8efe8
leaq 0x1904c(%rip), %rsi     # 0x71a49
movl $0x21, %edx
callq 0x8330
movq 0x365da(%rip), %rdi     # 0x8efe8
leaq 0x169ab(%rip), %rsi     # 0x6f3c0
movl $0x1, %edx
callq 0x8330
movq 0x365c2(%rip), %rdi     # 0x8efe8
movl $0x9e, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
movl $0xff, %edi
callq 0x8380
jmp 0x58a44
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x45cd2
leaq 0x40(%rsp), %rdi
callq 0x45cd2
movq %rbx, %rdi
callq 0x8540
nop