// File: luooofan[P]hblzbd_compiler/src/Pass/dead_code_eliminate.cpp
// Function: DeadCodeEliminate::FindNoSideEffectFunc(SSAModule*, std::unordered_set<SSAFunction*, std::hash<SSAFunction*>, std::equal_to<SSAFunction*>, std::allocator<SSAFunction*>>&)
void DeadCodeEliminate::FindNoSideEffectFunc(SSAModule* m, std::unordered_set<SSAFunction*>& no_side_effect_funcs) {
  // NOTE: 这里并没有把副作用的信息记录到函数中
  // 没有副作用的函数为 1.函数自身没有对数组类型参数和全局量有赋值(store)行为 2.同时没有调用有副作用的函数
  // 具体来说 如果函数pointer类型的argument的使用没有store语句 用了的globalvariable的使用也只有load语句即满足第一点
  no_side_effect_funcs.clear();
  for (auto func : m->GetFuncList()) {
    no_side_effect_funcs.insert(func);
  }

  // 每个builtin函数都是有副作用的
  for (auto builtin_func : m->GetBuiltinFuncList()) {
    no_side_effect_funcs.insert(builtin_func);
    RemoveFromNoSideEffectFuncs(builtin_func, no_side_effect_funcs);
  }

  for (auto func : m->GetFuncList()) {
    if (no_side_effect_funcs.find(func) == no_side_effect_funcs.end()) continue;
    bool has_side_effect = false;
    for (Argument* arg : func->GetValue()->GetArgList()) {
      for (Use* use : arg->GetUses()) {
        if (nullptr != dynamic_cast<StoreInst*>(use->GetUser())) goto setflag;
      }
    }
    for (GlobalVariable* glo : func->GetUsedGlobVarList()) {
      for (Use* use : glo->GetUses()) {
        auto inst = dynamic_cast<SSAInstruction*>(use->GetUser());
        MyAssert(nullptr != inst);
        if (func == inst->GetParent()->GetFunction()) {
          if (nullptr != dynamic_cast<StoreInst*>(inst)) goto setflag;
        }
      }
    }
    continue;
  setflag:
    has_side_effect = true;
    // propagate to caller
    RemoveFromNoSideEffectFuncs(func, no_side_effect_funcs);
  }
#ifdef DEBUG_DEAD_CODE_ELIMINATE_PROCESS
  std::cout << "No side effect functions: ";
  for (auto func : no_side_effect_funcs) {
    std::cout << func->GetFuncName() << " ";
  }
  std::cout << std::endl;
#endif
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x160(%rsp)
movq %rsi, 0x158(%rsp)
movq 0x158(%rsp), %rdi
callq 0x62850
movq 0x160(%rsp), %rdi
callq 0xa0ee0
movq %rax, 0x150(%rsp)
movq 0x150(%rsp), %rdi
callq 0x624d0
movq %rax, 0x148(%rsp)
movq 0x150(%rsp), %rdi
callq 0x62500
movq %rax, 0x140(%rsp)
leaq 0x148(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x62530
testb $0x1, %al
jne 0x9f75e
jmp 0x9f7a9
leaq 0x148(%rsp), %rdi
callq 0x62550
movq (%rax), %rax
movq %rax, 0x138(%rsp)
movq 0x158(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x62980
movq %rax, 0x128(%rsp)
movb %dl, 0x130(%rsp)
leaq 0x148(%rsp), %rdi
callq 0x62570
jmp 0x9f743
movq 0x160(%rsp), %rdi
callq 0xa1110
movq %rax, 0x120(%rsp)
movq 0x120(%rsp), %rdi
callq 0x624d0
movq %rax, 0x118(%rsp)
movq 0x120(%rsp), %rdi
callq 0x62500
movq %rax, 0x110(%rsp)
leaq 0x118(%rsp), %rdi
leaq 0x110(%rsp), %rsi
callq 0x62530
testb $0x1, %al
jne 0x9f803
jmp 0x9f863
leaq 0x118(%rsp), %rdi
callq 0x62550
movq (%rax), %rax
movq %rax, 0x108(%rsp)
movq 0x158(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x62980
movq %rax, 0xf8(%rsp)
movb %dl, 0x100(%rsp)
movq 0x108(%rsp), %rdi
movq 0x158(%rsp), %rsi
callq 0xa0d40
leaq 0x118(%rsp), %rdi
callq 0x62570
jmp 0x9f7e8
movq 0x160(%rsp), %rdi
callq 0xa0ee0
movq %rax, 0xf0(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x624d0
movq %rax, 0xe8(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x62500
movq %rax, 0xe0(%rsp)
leaq 0xe8(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x62530
testb $0x1, %al
jne 0x9f8c0
jmp 0x9fcc5
leaq 0xe8(%rsp), %rdi
callq 0x62550
movq (%rax), %rax
movq %rax, 0xd8(%rsp)
movq 0x158(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0xa0f50
movq %rax, 0xd0(%rsp)
movq 0x158(%rsp), %rdi
callq 0x62a60
movq %rax, 0xc8(%rsp)
leaq 0xd0(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0xa10f0
testb $0x1, %al
jne 0x9f925
jmp 0x9f92a
jmp 0x9fcb3
movb $0x0, 0xc7(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x62a20
movq %rax, %rdi
callq 0xa1120
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rdi
callq 0xa1130
movq %rax, 0xb0(%rsp)
movq 0xb8(%rsp), %rdi
callq 0xa1160
movq %rax, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0xa1190
testb $0x1, %al
jne 0x9f997
jmp 0x9faa1
leaq 0xb0(%rsp), %rdi
callq 0xa11b0
movq (%rax), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x5e2d0
movq %rax, 0x98(%rsp)
movq 0x98(%rsp), %rdi
callq 0x5e160
movq %rax, 0x90(%rsp)
movq 0x98(%rsp), %rdi
callq 0x5e1b0
movq %rax, 0x88(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x5e190
testb $0x1, %al
jne 0x9fa0c
jmp 0x9fa8d
leaq 0x90(%rsp), %rdi
callq 0x5e1e0
movq (%rax), %rax
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rdi
callq 0x60410
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0x9fa5f
movq 0x30(%rsp), %rdi
leaq 0xabbc8(%rip), %rsi     # 0x14b610
leaq 0xabdc1(%rip), %rdx     # 0x14b810
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x28(%rsp)
jmp 0x9fa68
xorl %eax, %eax
movq %rax, 0x28(%rsp)
jmp 0x9fa68
movq 0x28(%rsp), %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0x9fa79
jmp 0x9fc96
jmp 0x9fa7b
leaq 0x90(%rsp), %rdi
callq 0x5e280
jmp 0x9f9ee
jmp 0x9fa8f
leaq 0xb0(%rsp), %rdi
callq 0xa11e0
jmp 0x9f979
movq 0xd8(%rsp), %rdi
callq 0xa1200
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rdi
callq 0x62b10
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rdi
callq 0x62b40
movq %rax, 0x68(%rsp)
leaq 0x70(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x62b70
testb $0x1, %al
jne 0x9fae9
jmp 0x9fc94
leaq 0x70(%rsp), %rdi
callq 0x62b90
movq (%rax), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rdi
callq 0x5e2d0
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
callq 0x5e160
movq %rax, 0x50(%rsp)
movq 0x58(%rsp), %rdi
callq 0x5e1b0
movq %rax, 0x48(%rsp)
leaq 0x50(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x5e190
testb $0x1, %al
jne 0x9fb40
jmp 0x9fc83
leaq 0x50(%rsp), %rdi
callq 0x5e1e0
movq (%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rdi
callq 0x60410
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x9fb8a
movq 0x20(%rsp), %rdi
leaq 0xaba9d(%rip), %rsi     # 0x14b610
leaq 0xab89e(%rip), %rdx     # 0x14b418
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x18(%rsp)
jmp 0x9fb93
xorl %eax, %eax
movq %rax, 0x18(%rsp)
jmp 0x9fb93
movq 0x18(%rsp), %rax
movq %rax, 0x38(%rsp)
xorl %eax, %eax
cmpq 0x38(%rsp), %rax
jne 0x9fbfd
movq 0xac43b(%rip), %rdi     # 0x14bfe8
leaq 0x5a544(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, %rdi
leaq 0x5dd13(%rip), %rsi     # 0xfd8d6
callq 0x8330
movq %rax, %rdi
leaq 0x5b818(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, %rdi
movl $0x96, %esi
callq 0x8650
movq %rax, %rdi
movq 0xac392(%rip), %rsi     # 0x14bf80
callq 0x8380
movl $0xff, %edi
callq 0x8460
movq 0xd8(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x38(%rsp), %rdi
callq 0x5e2b0
movq %rax, %rdi
callq 0x5e2c0
movq %rax, %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
jne 0x9fc72
movq 0x38(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x9fc5b
movq 0x8(%rsp), %rdi
leaq 0xab7d3(%rip), %rsi     # 0x14b418
leaq 0xabbc4(%rip), %rdx     # 0x14b810
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, (%rsp)
jmp 0x9fc63
xorl %eax, %eax
movq %rax, (%rsp)
jmp 0x9fc63
movq (%rsp), %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0x9fc70
jmp 0x9fc96
jmp 0x9fc72
jmp 0x9fc74
leaq 0x50(%rsp), %rdi
callq 0x5e280
jmp 0x9fb28
jmp 0x9fc85
leaq 0x70(%rsp), %rdi
callq 0x62bb0
jmp 0x9fad1
jmp 0x9fcb3
movb $0x1, 0xc7(%rsp)
movq 0xd8(%rsp), %rdi
movq 0x158(%rsp), %rsi
callq 0xa0d40
leaq 0xe8(%rsp), %rdi
callq 0x62570
jmp 0x9f8a2
addq $0x168, %rsp            # imm = 0x168
retq
nopl (%rax)