// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/src/vmir_transform.c
// Function: exit_ssa_edge
static void
exit_ssa_edge(ir_unit_t *iu, ir_function_t *f, ir_bb_t *bb,
              ir_bb_edge_t *ibe)
{
  phi_lift_node_t *dst, *src;
  phi_lift_egde_t *ple, *ple_next;
  ir_instr_t *ii;
  struct phi_lift_node_list nodes;
  struct phi_lift_edge_list edges;

  LIST_INIT(&nodes);
  LIST_INIT(&edges);
  ir_bb_t *prebb = ibe->ibe_from;
  const int predecessor = prebb->ib_id;

  TAILQ_FOREACH(ii, &bb->ib_instrs, ii_link) {
    if(ii->ii_class != IR_IC_PHI)
      break;

    ir_instr_phi_t *iip = (ir_instr_phi_t *)ii;
    for(int i = 0; i < iip->num_nodes; i++) {
      if(iip->nodes[i].predecessor != predecessor)
        continue;

      if(iip->super.ii_ret.value == iip->nodes[i].value.value)
        continue;

      dst = phi_lift_node_find(&nodes, iip->super.ii_ret.value);
      if(dst == NULL) {
        dst = alloca(sizeof(phi_lift_node_t));
        phi_lift_node_init(&nodes, dst, iip->super.ii_ret);
      }

      src = phi_lift_node_find(&nodes, iip->nodes[i].value.value);
      if(src == NULL) {
        src = alloca(sizeof(phi_lift_node_t));
        phi_lift_node_init(&nodes, src, iip->nodes[i].value);
      }
      if(dst->pln_dst != NULL)
        parser_error(iu, "Multiple PHI entries point to same register");

      ple = alloca(sizeof(phi_lift_egde_t));
      ple->ple_src = src;
      ple->ple_dst = dst;
      LIST_INSERT_HEAD(&src->pln_src, ple, ple_src_link);
      dst->pln_dst = ple;
      LIST_INSERT_HEAD(&edges,        ple, ple_link);
    }
  }

  if(LIST_FIRST(&edges) == NULL)
    return;

  // First moves where destination is not also a source
  ir_instr_t *last = TAILQ_LAST(&prebb->ib_instrs, ir_instr_queue);


  while(1) {
    int progress = 0;

    for(ple = LIST_FIRST(&edges); ple != NULL; ple = ple_next) {
      ple_next = LIST_NEXT(ple, ple_link);
      if(LIST_FIRST(&ple->ple_dst->pln_src) != NULL)
        continue;

      insert_move(iu, ple->ple_dst->pln_vt, ple->ple_src->pln_vt, last);

      progress = 1;
      LIST_REMOVE(ple, ple_link);
      LIST_REMOVE(ple, ple_src_link);
      LIST_REMOVE(ple->ple_dst, pln_link);
      if(LIST_FIRST(&ple->ple_src->pln_src) == NULL)
        LIST_REMOVE(ple->ple_src, pln_link);
    }

    if(LIST_FIRST(&edges) == NULL)
      return;

    if(!progress)
      break;
  }



  while(1) {
    phi_lift_node_t *start = LIST_FIRST(&nodes);
    if(start == NULL)
      break;
    // Add a move to temporary register to resolve cycle

    ir_valuetype_t tmpreg = value_alloc_temporary(iu, start->pln_vt.type);
    insert_move(iu, tmpreg, start->pln_vt, last);

    phi_lift_node_t *cur = start;
    while(1) {
      phi_lift_node_t *src = cur->pln_dst->ple_src;
      if(src == start)
        break;

      insert_move(iu, cur->pln_vt, src->pln_vt, last);
      LIST_REMOVE(cur, pln_link);
      cur = src;
    }

    insert_move(iu, cur->pln_vt, tmpreg, last);
    LIST_REMOVE(cur, pln_link);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq $0x0, -0x50(%rbp)
jmp 0x27b05
movq $0x0, -0x58(%rbp)
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, -0x64(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x27d39
movq -0x48(%rbp), %rax
cmpl $0x9, 0x28(%rax)
je 0x27b49
jmp 0x27d39
movq -0x48(%rbp), %rax
movq %rax, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
movq -0x70(%rbp), %rcx
cmpl 0x58(%rcx), %eax
jge 0x27d27
movq -0x70(%rbp), %rax
addq $0x5c, %rax
movslq -0x74(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
cmpl -0x64(%rbp), %eax
je 0x27b87
jmp 0x27d19
movq -0x70(%rbp), %rax
movl 0x2c(%rax), %eax
movq -0x70(%rbp), %rcx
addq $0x5c, %rcx
movslq -0x74(%rbp), %rdx
imulq $0xc, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x4(%rcx), %eax
jne 0x27bab
jmp 0x27d19
movq -0x70(%rbp), %rax
movl 0x2c(%rax), %esi
leaq -0x50(%rbp), %rdi
callq 0x28060
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x27be9
movq %rsp, %rax
addq $-0x30, %rax
movq %rax, %rsp
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rsi
movq -0x70(%rbp), %rax
movq 0x2c(%rax), %rdx
leaq -0x50(%rbp), %rdi
callq 0x280b0
movq -0x70(%rbp), %rax
addq $0x5c, %rax
movslq -0x74(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl 0x4(%rax), %esi
leaq -0x50(%rbp), %rdi
callq 0x28060
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x27c45
movq %rsp, %rax
addq $-0x30, %rax
movq %rax, %rsp
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rsi
movq -0x70(%rbp), %rax
addq $0x5c, %rax
movslq -0x74(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq 0x4(%rax), %rdx
leaq -0x50(%rbp), %rdi
callq 0x280b0
movq -0x28(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x27c6e
movq -0x8(%rbp), %rdi
leaq 0x17792(%rip), %rsi     # 0x3f3ed
movl $0x3a8, %edx            # imm = 0x3A8
leaq 0x17bb6(%rip), %rcx     # 0x3f81d
movb $0x0, %al
callq 0x18220
movq %rsp, %rax
addq $-0x30, %rax
movq %rax, %rsp
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x38(%rbp), %rcx
movq %rax, 0x10(%rcx)
cmpq $0x0, %rax
je 0x27cbe
movq -0x38(%rbp), %rcx
addq $0x10, %rcx
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rcx
addq $0x10, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x58(%rbp), %rax
movq -0x38(%rbp), %rcx
movq %rax, (%rcx)
cmpq $0x0, %rax
je 0x27d03
movq -0x38(%rbp), %rcx
movq -0x58(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq -0x58(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x27d19
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x27b58
jmp 0x27d29
movq -0x48(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x27b2f
cmpq $0x0, -0x58(%rbp)
jne 0x27d45
jmp 0x2804d
movq -0x60(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq %rax, -0x80(%rbp)
movl $0x0, -0x84(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x27ed0
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
cmpq $0x0, 0x10(%rax)
je 0x27d94
jmp 0x27ec3
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rdx
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x80(%rbp), %rcx
movq 0x20(%rdx), %rsi
movq 0x20(%rax), %rdx
callq 0x28130
movl $0x1, -0x84(%rbp)
movq -0x38(%rbp), %rax
cmpq $0x0, (%rax)
je 0x27de0
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
jmp 0x27df4
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x27e13
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, (%rax)
jmp 0x27e28
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
cmpq $0x0, (%rax)
je 0x27e51
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
cmpq $0x0, 0x10(%rax)
jne 0x27ec1
jmp 0x27e7c
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
cmpq $0x0, (%rax)
je 0x27ea5
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
jmp 0x27ec1
jmp 0x27ec3
movq -0x40(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x27d6a
cmpq $0x0, -0x58(%rbp)
jne 0x27edc
jmp 0x2804d
cmpl $0x0, -0x84(%rbp)
jne 0x27ee7
jmp 0x27eec
jmp 0x27d58
jmp 0x27eee
movq -0x50(%rbp), %rax
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
jne 0x27f08
jmp 0x2804d
movq -0x8(%rbp), %rdi
movq -0x90(%rbp), %rax
movl 0x24(%rax), %esi
callq 0x20c80
movq %rax, -0x98(%rbp)
movq -0x8(%rbp), %rdi
movq -0x90(%rbp), %rax
movq -0x80(%rbp), %rcx
movq -0x98(%rbp), %rsi
movq 0x20(%rax), %rdx
callq 0x28130
movq -0x90(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
cmpq -0x90(%rbp), %rax
jne 0x27f77
jmp 0x27feb
movq -0x8(%rbp), %rdi
movq -0xa0(%rbp), %rdx
movq -0xa8(%rbp), %rax
movq -0x80(%rbp), %rcx
movq 0x20(%rdx), %rsi
movq 0x20(%rax), %rdx
callq 0x28130
movq -0xa0(%rbp), %rax
cmpq $0x0, (%rax)
je 0x27fc0
movq -0xa0(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0xa0(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq -0xa0(%rbp), %rax
movq (%rax), %rcx
movq -0xa0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
movq -0xa8(%rbp), %rax
movq %rax, -0xa0(%rbp)
jmp 0x27f4f
movq -0x8(%rbp), %rdi
movq -0xa0(%rbp), %rax
movq -0x80(%rbp), %rcx
movq 0x20(%rax), %rsi
movq -0x98(%rbp), %rdx
callq 0x28130
movq -0xa0(%rbp), %rax
cmpq $0x0, (%rax)
je 0x28030
movq -0xa0(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0xa0(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq -0xa0(%rbp), %rax
movq (%rax), %rcx
movq -0xa0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
jmp 0x27eee
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)