// File: luooofan[P]hblzbd_compiler/src/Pass/loop_invariant_extrapolation.cpp
// Function: walk(IRBasicBlock*, std::set<int, std::less<int>, std::allocator<int>>, std::map<int, IRBasicBlock*, std::less<int>, std::allocator<std::pair<int const, IRBasicBlock*>>>, std::vector<int, std::allocator<int>>, std::map<IRBasicBlock*, int, std::less<IRBasicBlock*>, std::allocator<std::pair<IRBasicBlock* const, int>>>)
vector<IRBasicBlock*> walk(IRBasicBlock* enter, set<int> in_loop, map<int, IRBasicBlock*> id_bb, vector<int> loop,
                           map<IRBasicBlock*, int> bb_id) {
  set<IRBasicBlock*> new_in_loop;
  for (auto it : in_loop) new_in_loop.insert(id_bb[it]);
  vector<IRBasicBlock*> new_loop;
  for (auto bid : loop) new_loop.push_back(id_bb[bid]);
  vector<IRBasicBlock*> res;
  if (enter->ir_list_.size() != 2) return res;
  res.push_back(enter);
  while (true) {
    auto bb = res[res.size() - 1];
    // 下面条件就是要求:后继必须是2个，并且1个指向loop内，1个指向loop外(只要求2个的话，有可能是ifelse)
    if (bb->succ_.size() == 2 && ((new_in_loop.find(bb->succ_[0]) == new_in_loop.end()) +
                                  (new_in_loop.find(bb->succ_[1]) == new_in_loop.end())) == 1) {
      auto nxt = new_in_loop.find(bb->succ_[0]) == new_in_loop.end() ? bb->succ_[1] : bb->succ_[0];
      if (nxt->ir_list_.size() != 1) break;
      res.push_back(nxt);
    } else
      break;
  }
  vector<IRBasicBlock*> res1;
  for (auto bb0 : res) {
    auto op1 = (*(bb0->ir_list_.rbegin()))->opn1_, op2 = (*(bb0->ir_list_.rbegin()))->opn2_;
    if (op1.scope_id_ == 0 || op2.scope_id_ == 0) continue;
    vector<ir::Opn> ops;
    ops.push_back(op1), ops.push_back(op2);
    if (op1.type_ == ir::Opn::Type::Array) ops.push_back(*op1.offset_);
    if (op2.type_ == ir::Opn::Type::Array) ops.push_back(*op2.offset_);
    bool flag = true;
    for (auto bb : new_loop) {
      for (auto ir : bb->ir_list_) {
        for (auto op : ops) {
          if (ir->res_.name_ == op.name_) {
            flag = false;
            break;
          }
        }
      }
    }
    if (flag) res1.push_back(bb0);
  }
  return res1;
}

// Assembly:
subq $0x358, %rsp            # imm = 0x358
movq %r8, 0x88(%rsp)
movq %rcx, 0x90(%rsp)
movq %rdx, 0xa8(%rsp)
movq %rdi, 0x98(%rsp)
movq %rdi, %rax
movq %rax, 0xa0(%rsp)
movq %rdi, 0x350(%rsp)
movq %rsi, 0x348(%rsp)
movq %rdx, 0x340(%rsp)
movq %rcx, 0x338(%rsp)
movq %r8, 0x330(%rsp)
movq %r9, 0x328(%rsp)
leaq 0x2f8(%rsp), %rdi
callq 0xd4e20
movq 0xa8(%rsp), %rdx
movq %rdx, 0x2f0(%rsp)
movq 0x2f0(%rsp), %rdi
callq 0x80b00
movq %rax, 0x2e8(%rsp)
movq 0x2f0(%rsp), %rdi
callq 0x80ab0
movq %rax, 0x2e0(%rsp)
leaq 0x2e8(%rsp), %rdi
leaq 0x2e0(%rsp), %rsi
callq 0x80a50
testb $0x1, %al
jne 0xcd557
jmp 0xcd5ef
leaq 0x2e8(%rsp), %rdi
callq 0x80b30
movq 0x90(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0x2dc(%rsp)
leaq 0x2dc(%rsp), %rsi
callq 0xd4c10
movq %rax, 0x80(%rsp)
jmp 0xcd58c
movq 0x80(%rsp), %rsi
leaq 0x2f8(%rsp), %rdi
callq 0xd4e30
movb %dl, 0x77(%rsp)
movq %rax, 0x78(%rsp)
jmp 0xcd5ac
movb 0x77(%rsp), %al
movq 0x78(%rsp), %rcx
movq %rcx, 0x2b8(%rsp)
movb %al, 0x2c0(%rsp)
leaq 0x2e8(%rsp), %rdi
callq 0x80b50
jmp 0xcd539
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0xcdeac
leaq 0x2a0(%rsp), %rdi
callq 0x18ae0
movq 0x88(%rsp), %rax
movq %rax, 0x298(%rsp)
movq 0x298(%rsp), %rdi
callq 0x1fc30
movq %rax, 0x290(%rsp)
movq 0x298(%rsp), %rdi
callq 0x1f470
movq %rax, 0x288(%rsp)
leaq 0x290(%rsp), %rdi
leaq 0x288(%rsp), %rsi
callq 0x37210
testb $0x1, %al
jne 0xcd651
jmp 0xcd6c1
leaq 0x290(%rsp), %rdi
callq 0x37250
movq 0x90(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0x284(%rsp)
leaq 0x284(%rsp), %rsi
callq 0xd4c10
movq %rax, 0x68(%rsp)
jmp 0xcd683
movq 0x68(%rsp), %rsi
leaq 0x2a0(%rsp), %rdi
callq 0x186f0
jmp 0xcd697
jmp 0xcd699
leaq 0x290(%rsp), %rdi
callq 0x37260
jmp 0xcd636
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0xcde9f
leaq 0x268(%rsp), %rdi
callq 0x18ae0
movq 0x348(%rsp), %rdi
addq $0x8, %rdi
callq 0x18440
cmpq $0x2, %rax
je 0xcd70a
movq 0x98(%rsp), %rdi
leaq 0x268(%rsp), %rsi
callq 0xd4e90
movl $0x1, 0x264(%rsp)
jmp 0xcde5b
leaq 0x268(%rsp), %rdi
leaq 0x348(%rsp), %rsi
callq 0x186f0
jmp 0xcd721
jmp 0xcd723
jmp 0xcd725
leaq 0x268(%rsp), %rdi
callq 0x1cd80
movq %rax, %rsi
subq $0x1, %rsi
leaq 0x268(%rsp), %rdi
callq 0x8ee50
movq (%rax), %rax
movq %rax, 0x258(%rsp)
movq 0x258(%rsp), %rdi
addq $0x40, %rdi
callq 0x1cd80
movq %rax, %rcx
xorl %eax, %eax
cmpq $0x2, %rcx
movb %al, 0x67(%rsp)
jne 0xcd85d
movq 0x258(%rsp), %rdi
addq $0x40, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8ee50
movq %rax, %rsi
leaq 0x2f8(%rsp), %rdi
callq 0xd4ee0
movq %rax, 0x58(%rsp)
jmp 0xcd7a1
movq 0x58(%rsp), %rax
movq %rax, 0x250(%rsp)
leaq 0x2f8(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0xd4f20
movq %rax, 0x248(%rsp)
leaq 0x250(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0xd4ec0
movzbl %al, %eax
movl %eax, 0x44(%rsp)
movq 0x258(%rsp), %rdi
addq $0x40, %rdi
movl $0x1, %esi
callq 0x8ee50
movq 0x48(%rsp), %rdi
movq %rax, %rsi
callq 0xd4ee0
movq %rax, 0x50(%rsp)
jmp 0xcd80e
movq 0x50(%rsp), %rax
movq %rax, 0x240(%rsp)
leaq 0x2f8(%rsp), %rdi
callq 0xd4f20
movq %rax, 0x238(%rsp)
leaq 0x240(%rsp), %rdi
leaq 0x238(%rsp), %rsi
callq 0xd4ec0
movb %al, %cl
movl 0x44(%rsp), %eax
andb $0x1, %cl
movzbl %cl, %ecx
addl %ecx, %eax
cmpl $0x1, %eax
sete %al
movb %al, 0x67(%rsp)
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0xcd86a
jmp 0xcd968
movq 0x258(%rsp), %rdi
addq $0x40, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8ee50
movq %rax, %rsi
leaq 0x2f8(%rsp), %rdi
callq 0xd4ee0
movq %rax, 0x38(%rsp)
jmp 0xcd896
movq 0x38(%rsp), %rax
movq %rax, 0x228(%rsp)
leaq 0x2f8(%rsp), %rdi
callq 0xd4f20
movq %rax, 0x220(%rsp)
leaq 0x228(%rsp), %rdi
leaq 0x220(%rsp), %rsi
callq 0xd4ec0
testb $0x1, %al
jne 0xcd8d3
jmp 0xcd8f3
movq 0x258(%rsp), %rdi
addq $0x40, %rdi
movl $0x1, %esi
callq 0x8ee50
movq (%rax), %rax
movq %rax, 0x30(%rsp)
jmp 0xcd910
movq 0x258(%rsp), %rdi
addq $0x40, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8ee50
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x230(%rsp)
movq 0x230(%rsp), %rdi
addq $0x8, %rdi
callq 0x18440
cmpq $0x1, %rax
je 0xcd94f
jmp 0xcd96f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0xcde92
leaq 0x268(%rsp), %rdi
leaq 0x230(%rsp), %rsi
callq 0x186f0
jmp 0xcd966
jmp 0xcd96a
jmp 0xcd96f
jmp 0xcd723
movq 0x98(%rsp), %rdi
movb $0x0, 0x21f(%rsp)
callq 0x18ae0
leaq 0x268(%rsp), %rax
movq %rax, 0x210(%rsp)
movq 0x210(%rsp), %rdi
callq 0x1cc40
movq %rax, 0x208(%rsp)
movq 0x210(%rsp), %rdi
callq 0x1cac0
movq %rax, 0x200(%rsp)
leaq 0x208(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x492e0
testb $0x1, %al
jne 0xcd9dc
jmp 0xcde20
leaq 0x208(%rsp), %rdi
callq 0x49320
movq (%rax), %rax
movq %rax, 0x1f8(%rsp)
movq 0x1f8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x1b0(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0xd4f50
movq 0x20(%rsp), %rdi
callq 0xd4fa0
movq %rax, 0x28(%rsp)
jmp 0xcda23
movq 0x28(%rsp), %rax
movq (%rax), %rsi
addq $0x8, %rsi
leaq 0x1b8(%rsp), %rdi
callq 0x43130
jmp 0xcda3e
movq 0x1f8(%rsp), %rsi
addq $0x8, %rsi
leaq 0x168(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0xd4f50
movq 0x10(%rsp), %rdi
callq 0xd4fa0
movq %rax, 0x18(%rsp)
jmp 0xcda6d
movq 0x18(%rsp), %rax
movq (%rax), %rsi
addq $0x48, %rsi
leaq 0x170(%rsp), %rdi
callq 0x43130
jmp 0xcda88
cmpl $0x0, 0x1e0(%rsp)
je 0xcda9c
cmpl $0x0, 0x198(%rsp)
jne 0xcdade
movl $0x9, 0x264(%rsp)
jmp 0xcddd4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0xcde4c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0xcde11
leaq 0x150(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x39d60
movq 0x8(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
callq 0xd4fd0
jmp 0xcdb04
leaq 0x150(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0xd4fd0
jmp 0xcdb1b
cmpl $0x5, 0x1b8(%rsp)
jne 0xcdb71
movq 0x1e8(%rsp), %rsi
leaq 0x150(%rsp), %rdi
callq 0xd4fd0
jmp 0xcdb3c
jmp 0xcdb71
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
leaq 0x150(%rsp), %rdi
callq 0x48670
leaq 0x170(%rsp), %rdi
callq 0x1f210
jmp 0xcde11
cmpl $0x5, 0x170(%rsp)
jne 0xcdb94
movq 0x1a0(%rsp), %rsi
leaq 0x150(%rsp), %rdi
callq 0xd4fd0
jmp 0xcdb92
jmp 0xcdb94
movb $0x1, 0x14f(%rsp)
leaq 0x2a0(%rsp), %rax
movq %rax, 0x140(%rsp)
movq 0x140(%rsp), %rdi
callq 0x1cc40
movq %rax, 0x138(%rsp)
movq 0x140(%rsp), %rdi
callq 0x1cac0
movq %rax, 0x130(%rsp)
leaq 0x138(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0x492e0
testb $0x1, %al
jne 0xcdbf4
jmp 0xcdd99
leaq 0x138(%rsp), %rdi
callq 0x49320
movq (%rax), %rax
movq %rax, 0x128(%rsp)
movq 0x128(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x120(%rsp)
movq 0x120(%rsp), %rdi
callq 0x1b070
movq %rax, 0x118(%rsp)
movq 0x120(%rsp), %rdi
callq 0x1aeb0
movq %rax, 0x110(%rsp)
leaq 0x118(%rsp), %rdi
leaq 0x110(%rsp), %rsi
callq 0x493c0
testb $0x1, %al
jne 0xcdc68
jmp 0xcdd85
leaq 0x118(%rsp), %rdi
callq 0x1b4d0
movq (%rax), %rax
movq %rax, 0x108(%rsp)
leaq 0x150(%rsp), %rax
movq %rax, 0x100(%rsp)
movq 0x100(%rsp), %rdi
callq 0x47fb0
movq %rax, 0xf8(%rsp)
movq 0x100(%rsp), %rdi
callq 0x47fe0
movq %rax, 0xf0(%rsp)
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x48010
testb $0x1, %al
jne 0xcdcd8
jmp 0xcdd71
leaq 0xf8(%rsp), %rdi
callq 0x48050
movq %rax, %rsi
leaq 0xb0(%rsp), %rdi
callq 0x43130
jmp 0xcdcf7
movq 0x108(%rsp), %rdi
addq $0x88, %rdi
addq $0x8, %rdi
leaq 0xb0(%rsp), %rsi
addq $0x8, %rsi
callq 0x1a650
testb $0x1, %al
jne 0xcdd21
jmp 0xcdd36
movb $0x0, 0x14f(%rsp)
movl $0xe, 0x264(%rsp)
jmp 0xcdd41
movl $0x0, 0x264(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x1f210
movl 0x264(%rsp), %eax
testl %eax, %eax
je 0xcdd5d
jmp 0xcdd5b
jmp 0xcdd71
jmp 0xcdd5f
leaq 0xf8(%rsp), %rdi
callq 0x48060
jmp 0xcdcba
jmp 0xcdd73
leaq 0x118(%rsp), %rdi
callq 0x49460
jmp 0xcdc4a
jmp 0xcdd87
leaq 0x138(%rsp), %rdi
callq 0x49330
jmp 0xcdbd6
testb $0x1, 0x14f(%rsp)
je 0xcddbc
movq 0x98(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x186f0
jmp 0xcddba
jmp 0xcddbc
leaq 0x150(%rsp), %rdi
callq 0x48670
movl $0x0, 0x264(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x1f210
leaq 0x1b8(%rsp), %rdi
callq 0x1f210
movl 0x264(%rsp), %eax
testl %eax, %eax
je 0xcddfd
jmp 0xcddfb
jmp 0xcddff
jmp 0xcddff
leaq 0x208(%rsp), %rdi
callq 0x49330
jmp 0xcd9be
leaq 0x1b8(%rsp), %rdi
callq 0x1f210
jmp 0xcde4c
movb $0x1, 0x21f(%rsp)
movl $0x1, 0x264(%rsp)
testb $0x1, 0x21f(%rsp)
jne 0xcde4a
movq 0x98(%rsp), %rdi
callq 0x49360
jmp 0xcde5b
movq 0x98(%rsp), %rdi
callq 0x49360
jmp 0xcde92
leaq 0x268(%rsp), %rdi
callq 0x49360
leaq 0x2a0(%rsp), %rdi
callq 0x49360
leaq 0x2f8(%rsp), %rdi
callq 0xd5040
movq 0xa0(%rsp), %rax
addq $0x358, %rsp            # imm = 0x358
retq
leaq 0x268(%rsp), %rdi
callq 0x49360
leaq 0x2a0(%rsp), %rdi
callq 0x49360
leaq 0x2f8(%rsp), %rdi
callq 0xd5040
movq 0x2d0(%rsp), %rdi
callq 0x8670
nopw %cs:(%rax,%rax)