// File: /workspace/github_c_makefile_star2_O2/orangeduck[P]mpc/mpc.c
// Function: mpc_optimise_unretained
static void mpc_optimise_unretained(mpc_parser_t *p, int force) {

  int i, n, m;
  mpc_parser_t *t;

  if (p->retained && !force) { return; }

  /* Optimise Subexpressions */

  if (p->type == MPC_TYPE_EXPECT)     { mpc_optimise_unretained(p->data.expect.x, 0); }
  if (p->type == MPC_TYPE_APPLY)      { mpc_optimise_unretained(p->data.apply.x, 0); }
  if (p->type == MPC_TYPE_APPLY_TO)   { mpc_optimise_unretained(p->data.apply_to.x, 0); }
  if (p->type == MPC_TYPE_CHECK)      { mpc_optimise_unretained(p->data.check.x, 0); }
  if (p->type == MPC_TYPE_CHECK_WITH) { mpc_optimise_unretained(p->data.check_with.x, 0); }
  if (p->type == MPC_TYPE_PREDICT)    { mpc_optimise_unretained(p->data.predict.x, 0); }
  if (p->type == MPC_TYPE_NOT)        { mpc_optimise_unretained(p->data.not.x, 0); }
  if (p->type == MPC_TYPE_MAYBE)      { mpc_optimise_unretained(p->data.not.x, 0); }
  if (p->type == MPC_TYPE_MANY)       { mpc_optimise_unretained(p->data.repeat.x, 0); }
  if (p->type == MPC_TYPE_MANY1)      { mpc_optimise_unretained(p->data.repeat.x, 0); }
  if (p->type == MPC_TYPE_COUNT)      { mpc_optimise_unretained(p->data.repeat.x, 0); }
  if (p->type == MPC_TYPE_SEPBY1)     {
    mpc_optimise_unretained(p->data.sepby1.x, 0);
    mpc_optimise_unretained(p->data.sepby1.sep, 0);
  }

  if (p->type == MPC_TYPE_OR) {
    for(i = 0; i < p->data.or.n; i++) {
      mpc_optimise_unretained(p->data.or.xs[i], 0);
    }
  }

  if (p->type == MPC_TYPE_AND) {
    for(i = 0; i < p->data.and.n; i++) {
      mpc_optimise_unretained(p->data.and.xs[i], 0);
    }
  }

  /* Perform optimisations */

  while (1) {

    /* Merge rhs `or` */
    if (p->type == MPC_TYPE_OR
    &&  p->data.or.xs[p->data.or.n-1]->type == MPC_TYPE_OR
    && !p->data.or.xs[p->data.or.n-1]->retained) {
      t = p->data.or.xs[p->data.or.n-1];
      n = p->data.or.n; m = t->data.or.n;
      p->data.or.n = n + m - 1;
      p->data.or.xs = realloc(p->data.or.xs, sizeof(mpc_parser_t*) * (n + m -1));
      memmove(p->data.or.xs + n - 1, t->data.or.xs, m * sizeof(mpc_parser_t*));
      free(t->data.or.xs); free(t->name); free(t);
      continue;
    }

    /* Merge lhs `or` */
    if (p->type == MPC_TYPE_OR
    &&  p->data.or.xs[0]->type == MPC_TYPE_OR
    && !p->data.or.xs[0]->retained) {
      t = p->data.or.xs[0];
      n = p->data.or.n; m = t->data.or.n;
      p->data.or.n = n + m - 1;
      p->data.or.xs = realloc(p->data.or.xs, sizeof(mpc_parser_t*) * (n + m -1));
      memmove(p->data.or.xs + m, p->data.or.xs + 1, (n - 1) * sizeof(mpc_parser_t*));
      memmove(p->data.or.xs, t->data.or.xs, m * sizeof(mpc_parser_t*));
      free(t->data.or.xs); free(t->name); free(t);
      continue;
    }

    /* Remove ast `pass` */
    if (p->type == MPC_TYPE_AND
    &&  p->data.and.n == 2
    &&  p->data.and.xs[0]->type == MPC_TYPE_PASS
    && !p->data.and.xs[0]->retained
    &&  p->data.and.f == mpcf_fold_ast) {
      t = p->data.and.xs[1];
      mpc_delete(p->data.and.xs[0]);
      free(p->data.and.xs); free(p->data.and.dxs); free(p->name);
      memcpy(p, t, sizeof(mpc_parser_t));
      free(t);
      continue;
    }

    /* Merge ast lhs `and` */
    if (p->type == MPC_TYPE_AND
    &&  p->data.and.f == mpcf_fold_ast
    &&  p->data.and.xs[0]->type == MPC_TYPE_AND
    && !p->data.and.xs[0]->retained
    &&  p->data.and.xs[0]->data.and.f == mpcf_fold_ast) {
      t = p->data.and.xs[0];
      n = p->data.and.n; m = t->data.and.n;
      p->data.and.n = n + m - 1;
      p->data.and.xs = realloc(p->data.and.xs, sizeof(mpc_parser_t*) * (n + m - 1));
      p->data.and.dxs = realloc(p->data.and.dxs, sizeof(mpc_dtor_t) * (n + m - 1 - 1));
      memmove(p->data.and.xs + m, p->data.and.xs + 1, (n - 1) * sizeof(mpc_parser_t*));
      memmove(p->data.and.xs, t->data.and.xs, m * sizeof(mpc_parser_t*));
      for (i = 0; i < p->data.and.n-1; i++) { p->data.and.dxs[i] = (mpc_dtor_t)mpc_ast_delete; }
      free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
      continue;
    }

    /* Merge ast rhs `and` */
    if (p->type == MPC_TYPE_AND
    &&  p->data.and.f == mpcf_fold_ast
    &&  p->data.and.xs[p->data.and.n-1]->type == MPC_TYPE_AND
    && !p->data.and.xs[p->data.and.n-1]->retained
    &&  p->data.and.xs[p->data.and.n-1]->data.and.f == mpcf_fold_ast) {
      t = p->data.and.xs[p->data.and.n-1];
      n = p->data.and.n; m = t->data.and.n;
      p->data.and.n = n + m - 1;
      p->data.and.xs = realloc(p->data.and.xs, sizeof(mpc_parser_t*) * (n + m -1));
      p->data.and.dxs = realloc(p->data.and.dxs, sizeof(mpc_dtor_t) * (n + m - 1 - 1));
      memmove(p->data.and.xs + n - 1, t->data.and.xs, m * sizeof(mpc_parser_t*));
      for (i = 0; i < p->data.and.n-1; i++) { p->data.and.dxs[i] = (mpc_dtor_t)mpc_ast_delete; }
      free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
      continue;
    }

    /* Remove re `lift` */
    if (p->type == MPC_TYPE_AND
    &&  p->data.and.n == 2
    &&  p->data.and.xs[0]->type == MPC_TYPE_LIFT
    &&  p->data.and.xs[0]->data.lift.lf == mpcf_ctor_str
    && !p->data.and.xs[0]->retained
    &&  p->data.and.f == mpcf_strfold) {
      t = p->data.and.xs[1];
      mpc_delete(p->data.and.xs[0]);
      free(p->data.and.xs); free(p->data.and.dxs); free(p->name);
      memcpy(p, t, sizeof(mpc_parser_t));
      free(t);
      continue;
    }

    /* Merge re lhs `and` */
    if (p->type == MPC_TYPE_AND
    &&  p->data.and.f == mpcf_strfold
    &&  p->data.and.xs[0]->type == MPC_TYPE_AND
    && !p->data.and.xs[0]->retained
    &&  p->data.and.xs[0]->data.and.f == mpcf_strfold) {
      t = p->data.and.xs[0];
      n = p->data.and.n; m = t->data.and.n;
      p->data.and.n = n + m - 1;
      p->data.and.xs = realloc(p->data.and.xs, sizeof(mpc_parser_t*) * (n + m - 1));
      p->data.and.dxs = realloc(p->data.and.dxs, sizeof(mpc_dtor_t) * (n + m - 1 - 1));
      memmove(p->data.and.xs + m, p->data.and.xs + 1, (n - 1) * sizeof(mpc_parser_t*));
      memmove(p->data.and.xs, t->data.and.xs, m * sizeof(mpc_parser_t*));
      for (i = 0; i < p->data.and.n-1; i++) { p->data.and.dxs[i] = free; }
      free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
      continue;
    }

    /* Merge re rhs `and` */
    if (p->type == MPC_TYPE_AND
    &&  p->data.and.f == mpcf_strfold
    &&  p->data.and.xs[p->data.and.n-1]->type == MPC_TYPE_AND
    && !p->data.and.xs[p->data.and.n-1]->retained
    &&  p->data.and.xs[p->data.and.n-1]->data.and.f == mpcf_strfold) {
      t = p->data.and.xs[p->data.and.n-1];
      n = p->data.and.n; m = t->data.and.n;
      p->data.and.n = n + m - 1;
      p->data.and.xs = realloc(p->data.and.xs, sizeof(mpc_parser_t*) * (n + m -1));
      p->data.and.dxs = realloc(p->data.and.dxs, sizeof(mpc_dtor_t) * (n + m - 1 - 1));
      memmove(p->data.and.xs + n - 1, t->data.and.xs, m * sizeof(mpc_parser_t*));
      for (i = 0; i < p->data.and.n-1; i++) { p->data.and.dxs[i] = free; }
      free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
      continue;
    }

    return;

  }

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
testl %esi, %esi
jne 0xa9d1
cmpb $0x0, 0x31(%rbx)
je 0xa9d1
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb 0x30(%rbx), %al
cmpb $0x5, %al
jne 0xa9e6
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0xf, %al
jne 0xa9f8
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x10, %al
jne 0xaa0a
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x19, %al
jne 0xaa1c
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x1a, %al
jne 0xaa2e
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x11, %al
jne 0xaa40
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x12, %al
jne 0xaa52
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x13, %al
jne 0xaa64
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x14, %al
jne 0xaa76
movq 0x18(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x15, %al
jne 0xaa88
movq 0x18(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x16, %al
jne 0xaa9a
movq 0x18(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x1d, %al
jne 0xaab7
movq 0x18(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movq 0x20(%rbx), %rdi
xorl %esi, %esi
callq 0xa9aa
movb 0x30(%rbx), %al
cmpb $0x17, %al
jne 0xaade
xorl %r14d, %r14d
movslq 0x8(%rbx), %rax
cmpq %rax, %r14
jge 0xaadb
movq 0x10(%rbx), %rax
movq (%rax,%r14,8), %rdi
xorl %esi, %esi
callq 0xa9aa
incq %r14
jmp 0xaabe
movb 0x30(%rbx), %al
cmpb $0x18, %al
jne 0xab02
xorl %r14d, %r14d
movslq 0x8(%rbx), %rax
cmpq %rax, %r14
jge 0xab02
movq 0x18(%rbx), %rax
movq (%rax,%r14,8), %rdi
xorl %esi, %esi
callq 0xa9aa
incq %r14
jmp 0xaae5
movq 0x6417(%rip), %r13      # 0x10f20
movzbl 0x30(%rbx), %eax
cmpl $0x18, %eax
je 0xabac
cmpl $0x17, %eax
jne 0xa9c2
movq 0x10(%rbx), %rdi
movslq 0x8(%rbx), %r12
movq -0x8(%rdi,%r12,8), %r14
cmpb $0x17, 0x30(%r14)
jne 0xab3e
cmpb $0x0, 0x31(%r14)
je 0xad3c
movq (%rdi), %r14
cmpb $0x17, 0x30(%r14)
jne 0xa9c2
cmpb $0x0, 0x31(%r14)
jne 0xa9c2
movslq 0x8(%r14), %r15
movl %r12d, %ebp
decl %ebp
leal (%r12,%r15), %eax
decl %eax
movl %eax, 0x8(%rbx)
movslq %eax, %rsi
shlq $0x3, %rsi
callq 0x4610
movq %rax, %r12
movq %rax, 0x10(%rbx)
leaq (%rax,%r15,8), %rdi
leaq 0x8(%rax), %rsi
movslq %ebp, %rdx
shlq $0x3, %rdx
callq 0x4680
movq 0x10(%r14), %rsi
shlq $0x3, %r15
movq %r12, %rdi
movq %r15, %rdx
callq 0x4680
movq 0x10(%r14), %rdi
jmp 0xaf75
movslq 0x8(%rbx), %r12
cmpq $0x2, %r12
jne 0xabcd
movq 0x18(%rbx), %rcx
movq (%rcx), %rdi
cmpb $0x1, 0x30(%rdi)
jne 0xabcd
cmpb $0x0, 0x31(%rdi)
je 0xad6e
movq 0x10(%rbx), %rax
cmpq 0x63d0(%rip), %rax      # 0x10fa8
jne 0xac39
movq 0x18(%rbx), %rdi
movq (%rdi), %r14
cmpb $0x18, 0x30(%r14)
jne 0xac00
cmpb $0x0, 0x31(%r14)
jne 0xac00
movq 0x63b2(%rip), %rax      # 0x10fa8
cmpq %rax, 0x10(%r14)
je 0xae61
movq 0x18(%rbx), %rdi
movq -0x8(%rdi,%r12,8), %r14
cmpb $0x18, 0x30(%r14)
movq 0x6393(%rip), %rax      # 0x10fa8
jne 0xac39
cmpb $0x0, 0x31(%r14)
movq 0x6385(%rip), %rax      # 0x10fa8
jne 0xac39
movq 0x637c(%rip), %rcx      # 0x10fa8
movq %rcx, %rax
cmpq %rcx, 0x10(%r14)
je 0xaeef
cmpl $0x2, %r12d
jne 0xac63
movq 0x18(%rbx), %rcx
movq (%rcx), %rdi
cmpb $0x3, 0x30(%rdi)
jne 0xac63
movq 0x6325(%rip), %rdx      # 0x10f78
cmpq %rdx, 0x8(%rdi)
jne 0xac63
cmpb $0x0, 0x31(%rdi)
je 0xae0b
cmpq 0x6356(%rip), %rax      # 0x10fc0
jne 0xa9c2
movq 0x18(%rbx), %rdi
movq (%rdi), %r14
cmpb $0x18, 0x30(%r14)
jne 0xac96
cmpb $0x0, 0x31(%r14)
jne 0xac96
movq 0x6334(%rip), %rax      # 0x10fc0
cmpq %rax, 0x10(%r14)
je 0xad84
movq 0x18(%rbx), %rdi
movq -0x8(%rdi,%r12,8), %r14
cmpb $0x18, 0x30(%r14)
jne 0xa9c2
cmpb $0x0, 0x31(%r14)
jne 0xa9c2
movq 0x6304(%rip), %rax      # 0x10fc0
cmpq %rax, 0x10(%r14)
jne 0xa9c2
movslq 0x8(%r14), %r15
leaq (%r15,%r12), %rbp
leaq (%r15,%r12), %rax
decq %rax
movl %eax, 0x8(%rbx)
leaq -0x8(,%rbp,8), %rsi
callq 0x4610
movq %rax, 0x18(%rbx)
movq 0x20(%rbx), %rdi
movslq %ebp, %rax
leaq -0x10(,%rax,8), %rsi
callq 0x4610
movq %rax, 0x20(%rbx)
movq 0x18(%rbx), %rax
leaq (%rax,%r12,8), %rdi
addq $-0x8, %rdi
movq 0x18(%r14), %rsi
shlq $0x3, %r15
movq %r15, %rdx
callq 0x4680
xorl %eax, %eax
movslq 0x8(%rbx), %rcx
decq %rcx
cmpq %rcx, %rax
jge 0xaf68
movq 0x20(%rbx), %rcx
movq %r13, (%rcx,%rax,8)
incq %rax
jmp 0xad1f
movslq 0x8(%r14), %r15
leal (%r12,%r15), %eax
decl %eax
movl %eax, 0x8(%rbx)
movslq %eax, %rsi
shlq $0x3, %rsi
callq 0x4610
movq %rax, 0x10(%rbx)
leaq (%rax,%r12,8), %rdi
addq $-0x8, %rdi
movq 0x10(%r14), %rsi
shlq $0x3, %r15
jmp 0xab9b
movq 0x10(%rbx), %rax
cmpq 0x622f(%rip), %rax      # 0x10fa8
jne 0xac3f
jmp 0xae18
movslq 0x8(%r14), %r15
leaq (%r15,%r12), %rbp
leaq (%r15,%r12), %rax
decq %rax
movl %eax, 0x8(%rbx)
leaq -0x8(,%rbp,8), %rsi
callq 0x4610
movq %rax, 0x18(%rbx)
movq 0x20(%rbx), %rdi
movslq %ebp, %rax
leaq -0x10(,%rax,8), %rsi
callq 0x4610
movq %rax, 0x20(%rbx)
movq 0x18(%rbx), %rsi
leaq (%rsi,%r15,8), %rdi
addq $0x8, %rsi
leaq -0x8(,%r12,8), %rdx
callq 0x4680
movq 0x18(%rbx), %rdi
movq 0x18(%r14), %rsi
shlq $0x3, %r15
movq %r15, %rdx
callq 0x4680
xorl %eax, %eax
movslq 0x8(%rbx), %rcx
decq %rcx
cmpq %rcx, %rax
jge 0xaf68
movq 0x20(%rbx), %rcx
movq %r13, (%rcx,%rax,8)
incq %rax
jmp 0xadee
cmpq 0x61ae(%rip), %rax      # 0x10fc0
jne 0xa9c2
movq 0x8(%rcx), %r14
callq 0x4888
movq 0x18(%rbx), %rdi
callq 0x4880
movq 0x20(%rbx), %rdi
callq 0x4880
movq (%rbx), %rdi
callq 0x4880
movq 0x30(%r14), %rax
movq %rax, 0x30(%rbx)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups 0x20(%r14), %xmm2
movups %xmm2, 0x20(%rbx)
movups %xmm1, 0x10(%rbx)
movups %xmm0, (%rbx)
jmp 0xaf82
movslq 0x8(%r14), %r15
leaq (%r15,%r12), %rbp
leaq (%r15,%r12), %rax
decq %rax
movl %eax, 0x8(%rbx)
leaq -0x8(,%rbp,8), %rsi
callq 0x4610
movq %rax, 0x18(%rbx)
movq 0x20(%rbx), %rdi
movslq %ebp, %rax
leaq -0x10(,%rax,8), %rsi
callq 0x4610
movq %rax, 0x20(%rbx)
movq 0x18(%rbx), %rsi
leaq (%rsi,%r15,8), %rdi
addq $0x8, %rsi
leaq -0x8(,%r12,8), %rdx
callq 0x4680
movq 0x18(%rbx), %rdi
movq 0x18(%r14), %rsi
shlq $0x3, %r15
movq %r15, %rdx
callq 0x4680
xorl %eax, %eax
movq 0x60fe(%rip), %rdx      # 0x10fd0
movslq 0x8(%rbx), %rcx
decq %rcx
cmpq %rcx, %rax
jge 0xaf68
movq 0x20(%rbx), %rcx
movq %rdx, (%rcx,%rax,8)
incq %rax
jmp 0xaed2
movslq 0x8(%r14), %r15
leaq (%r15,%r12), %rbp
leaq (%r15,%r12), %rax
decq %rax
movl %eax, 0x8(%rbx)
leaq -0x8(,%rbp,8), %rsi
callq 0x4610
movq %rax, 0x18(%rbx)
movq 0x20(%rbx), %rdi
movslq %ebp, %rax
leaq -0x10(,%rax,8), %rsi
callq 0x4610
movq %rax, 0x20(%rbx)
movq 0x18(%rbx), %rax
leaq (%rax,%r12,8), %rdi
addq $-0x8, %rdi
movq 0x18(%r14), %rsi
shlq $0x3, %r15
movq %r15, %rdx
callq 0x4680
xorl %eax, %eax
movq 0x6081(%rip), %rdx      # 0x10fd0
movslq 0x8(%rbx), %rcx
decq %rcx
cmpq %rcx, %rax
jge 0xaf68
movq 0x20(%rbx), %rcx
movq %rdx, (%rcx,%rax,8)
incq %rax
jmp 0xaf4f
movq 0x18(%r14), %rdi
callq 0x4880
movq 0x20(%r14), %rdi
callq 0x4880
movq (%r14), %rdi
callq 0x4880
movq %r14, %rdi
callq 0x4880
jmp 0xab09